Android 房间数据库创建 - 回调
Android Room Database Creation - Callback
我在我的项目中使用 Android Room,我遇到了以下问题:
- Room 的数据库创建回调 (
RoomDatabase.Callback#onCreate
) 是否保证总是被调用?如果是这样,运行 在此回调中插入查询以预填充数据库是否安全 - 如果不执行,每次用户打开应用程序时都会导致应用程序崩溃的查询?
我问这个问题的原因是,目前,我正在我的应用程序上这样做。我正在利用该回调预填充我的数据库,但我看到一些用户反复发生崩溃。当应用程序尝试获取这些预填充数据之一,但它们不存在(返回 0 行)时,就会发生这些崩溃。
fun getInstance(context: Context): MyDatabaseClass {
if (isDeletingDatabase) throw DeletingDatabaseException()
if (instance == null) {
instance = Room
.databaseBuilder(context, MyDatabaseClass::class.java, MyDatabaseClass.DB_NAME)
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
onDbCreated(db)
}
})
.addMigrations(
Migration_1_2,
Migration_2_3
)
.build()
}
return instance!!
}
Is Room's database creation callback (RoomDatabase.Callback#onCreate)
guaranteed to always be called?
根据文档,在创建所有表后首次创建数据库时调用它。
未调用 onCreate()
的一种情况(尽管您可能期望它会调用)是未找到到当前版本的迁移并且在数据库构建器上设置了 fallbackToDestructiveMigration()
。在这种情况下,数据库会在不调用 onCreate()
的情况下重新创建。我不确定这是否是设计使然,但目前确实如此。
If so, is it safe to run insert queries in this callback to
prepopulate the database - queries which if not executed, will make
the app crash everytime the user opens it?
在这里填充数据库是安全的,假设它在您期望的时候被调用,根据我的理解,这只是在第一次创建数据库时。
因此,如果 Room 找不到某些版本的迁移项,如果您的应用未设计为处理丢失的数据,则可能会发生崩溃。
我对 Room 如何处理迁移的观察(截至 v2.2.0-alpha01):
根据 addMigrations()
的文档:
If a migration item is missing between current version and the latest
version, Room will clear the database and recreate..
可能是这样,但它也会抛出以下 IllegalStateException:
A migration from 1 to 2 was required but not found. Please provide the
necessary Migration path via
RoomDatabase.Builder.addMigration(Migration ...) or allow for
destructive migrations via one of the
RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
如果您将 fallbackToDestructiveMigration()
添加到您的数据库构建器,如异常所示,数据库会重新创建(或至少被擦除),但不会调用 onCreate()
,因此如果您的人口代码在那里,你最终将没有你的应用程序的数据。
出于这个原因,我相信 onCreate()
是填充数据库的可行选择,只要您承诺为 Room 提供它可能需要的所有必要迁移。
我在我的项目中使用 Android Room,我遇到了以下问题:
- Room 的数据库创建回调 (
RoomDatabase.Callback#onCreate
) 是否保证总是被调用?如果是这样,运行 在此回调中插入查询以预填充数据库是否安全 - 如果不执行,每次用户打开应用程序时都会导致应用程序崩溃的查询?
我问这个问题的原因是,目前,我正在我的应用程序上这样做。我正在利用该回调预填充我的数据库,但我看到一些用户反复发生崩溃。当应用程序尝试获取这些预填充数据之一,但它们不存在(返回 0 行)时,就会发生这些崩溃。
fun getInstance(context: Context): MyDatabaseClass {
if (isDeletingDatabase) throw DeletingDatabaseException()
if (instance == null) {
instance = Room
.databaseBuilder(context, MyDatabaseClass::class.java, MyDatabaseClass.DB_NAME)
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
onDbCreated(db)
}
})
.addMigrations(
Migration_1_2,
Migration_2_3
)
.build()
}
return instance!!
}
Is Room's database creation callback (RoomDatabase.Callback#onCreate) guaranteed to always be called?
根据文档,在创建所有表后首次创建数据库时调用它。
未调用 onCreate()
的一种情况(尽管您可能期望它会调用)是未找到到当前版本的迁移并且在数据库构建器上设置了 fallbackToDestructiveMigration()
。在这种情况下,数据库会在不调用 onCreate()
的情况下重新创建。我不确定这是否是设计使然,但目前确实如此。
If so, is it safe to run insert queries in this callback to prepopulate the database - queries which if not executed, will make the app crash everytime the user opens it?
在这里填充数据库是安全的,假设它在您期望的时候被调用,根据我的理解,这只是在第一次创建数据库时。
因此,如果 Room 找不到某些版本的迁移项,如果您的应用未设计为处理丢失的数据,则可能会发生崩溃。
我对 Room 如何处理迁移的观察(截至 v2.2.0-alpha01):
根据 addMigrations()
的文档:
If a migration item is missing between current version and the latest version, Room will clear the database and recreate..
可能是这样,但它也会抛出以下 IllegalStateException:
A migration from 1 to 2 was required but not found. Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...) or allow for destructive migrations via one of the RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
如果您将 fallbackToDestructiveMigration()
添加到您的数据库构建器,如异常所示,数据库会重新创建(或至少被擦除),但不会调用 onCreate()
,因此如果您的人口代码在那里,你最终将没有你的应用程序的数据。
出于这个原因,我相信 onCreate()
是填充数据库的可行选择,只要您承诺为 Room 提供它可能需要的所有必要迁移。