android - Android Room 预填充 SQL 数据库并持久更新
问题描述
我正在尝试使用 Kotlin 来:
- 从现有 SQL 数据库预填充我的应用程序中的房间数据库。
- 允许用户更新数据。
- 让更新的数据只保留当前版本。
- 让新版本清除旧数据并用新发布的 SQL 数据库替换它。
这是我到目前为止所做的:
我使用createFromAsset
方法通过调用预填充数据库,fallbackToDestructiveMigration()
如下所示:
@Database(entities = [MCData::class], version = 1, exportSchema = false)
abstract class MyRoom : RoomDatabase() {
abstract val myDao: MyDao
companion object {
@Volatile
private var INSTANCE: MyRoom? = null
fun getInstance(context: Context): MyRoom {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
MyRoom::class.java,
"mcdata.db")
.createFromAsset("mydata.db")
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
这是预先填充数据并让用户更改它,但是当应用程序重新启动时,初始填充后数据中的更新会丢失。我对这种行为感到困惑,因为fallbackToDestructiveMigration()
即使架构没有更改(用户只能更改两个现有列的值),代码似乎也在使用 刷新数据。
如果我删除该fallbackToDestructiveMigration()
方法,则初始预填充后用户的更新仍然存在,但是当我使用新数据重新安装应用程序时,数据库不会更新。
有没有办法让数据(包括编辑)保留在当前版本中,但在安装新版本时被新的预填充 SQL 数据库替换?
解决方案
我最终创建了两个构建器函数:
- 第一个在第一次安装或更新软件时调用,它从资产数据库中读取。
- 第二个在其他时候被调用,它从本地创建的数据库中读取,因此用户的小调整会持续到版本中。
@Database(entities = [MCData::class,FBData::class,WhereAmIdata::class], version = 1, exportSchema = false)
abstract class MyRoom : RoomDatabase() {
abstract val myDao: MyDao
companion object {
@Volatile // with volatile, changes immediately become visible to all threads
private var INSTANCE: MyRoom? = null
// this instantiaion is called the first time the software is updated
fun getInstanceAfterSoftwareUpdate(context: Context): MyRoom {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
MyRoom::class.java,
"mcdata")
.createFromAsset("mydata.db")
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
fun getInstance(context: Context): MyRoom {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
Log.i("MyRoom", "reading locally")
instance = Room.databaseBuilder(
context.applicationContext,
MyRoom:: class.java,
"mcdata"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
推荐阅读
- python - 存储为数据框列中列表的向量的 Seaborn 回归线图
- azure-data-factory - 寻找有关执行复杂 csv 到 json 数据流转换的建议
- plotly-dash - jupyterlab 中的 Dash 有时会因“127.0.0.1 拒绝连接”而失败
- pseudocode - 计算数组中存在多少“倒计时”序列
- xcode - 在 Xcode 中,是否可以排除 Apple Silicon 的源代码文件但将其包含在 Intel 中?
- python - 在 altair 图中为一些 x 标签着色?
- ruby-on-rails - 为什么我的 Rails 应用程序中的 lograge 会影响 ECS/Fargate 环境中的 CloudWatch 日志记录?
- arrays - 在结构指针代码中输入错误
- javascript - 在处理深度嵌套的对象数组时,在 map() 中使用多个 reduce() 函数的替代方法?
- java - JSON 对象无法从 START_OBJECT 令牌中反序列化 `java.lang.String` 的实例