Android Room数据库创建-回调

时间:2018-10-11 09:44:03

标签: android android-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!!
}

1 个答案:

答案 0 :(得分:0)

  

是Room的数据库创建回调(RoomDatabase.Callback#onCreate)   保证总是被叫?

根据文档,在创建所有表之后首次创建数据库时调用它。

未调用onCreate()(虽然您可能希望如此)的一种情况是找不到向当前版本的迁移,并且在数据库构建器上设置了fallbackToDestructiveMigration()。在这种情况下,无需调用onCreate()即可重新创建数据库。我不确定这是否是设计使然,但目前是这样。

  

如果是这样,在此回调中运行插入查询是否安全?   预填充数据库-查询,如果不执行,将使   用户每次打开应用程序都会崩溃吗?

在这里填充数据库是安全的,假设在您期望它被调用的时候就被调用,据我了解,这仅是在第一次创建数据库时。

因此,如果Room在某些版本中找不到迁移项目,那么如果您的应用程序未设计为处理丢失的数据,则可能会导致崩溃。


我对Room如何处理迁移的观察(自v2.2.0-alpha01起):

根据addMigrations()的文档:

  

如果当前版本和最新版本之间缺少迁移项目   版本,Room将清除数据库并重新创建。.

可能是这种情况,但它还会引发以下IllegalStateException:

  

需要从1迁移到2,但未找到。请提供   通过必要的迁移路径   RoomDatabase.Builder.addMigration(Migration ...)或允许   通过以下方式之一进行破坏性迁移   RoomDatabase.Builder.fallbackToDestructiveMigration *方法。

如果您将fallbackToDestructiveMigration()添加到数据库构建器中(如异常所示),则确实会重新创建(或至少清除了)数据库,但是不会调用onCreate(),因此如果您的填充代码在在那里,您最终将没有应用程序的数据。

因此,我相信onCreate()是填充数据库的可行选择,只要您承诺向Room提供它可能需要的所有必要迁移。