我正在开发一个Android应用程序,该应用程序带有在Android Room中运行的嵌入式SQLite数据库。我正在将应用程序从桌面Java迁移到Android,我需要将数据从与桌面应用程序一起使用的旧数据库导入Android数据库。当我尝试在Android应用程序中使用更改后的数据库时,我遇到了Room的问题。
我尝试使用Room创建的数据库文件,并使用为此编写的简短Java应用程序将数据从旧数据库移入该数据库。我只是清空相关表,从旧数据库中读取数据,然后将其插入新数据库中。
当我尝试将数据库文件移回我的Android设备并与Android应用程序一起使用时,出现了以下异常:
房间无法验证数据完整性。看起来您已更改架构,但忘记更新版本号。 您只需增加版本号即可解决此问题。
如果我在Room数据库代码中更改数据库的版本,则Room将需要一段代码来进行迁移,即使数据库的结构没有更改:
java.lang.IllegalStateException:需要从1迁移到2,但未找到。请通过RoomDatabase.Builder.addMigration(Migration ...)提供必要的迁移路径,或者允许通过RoomDatabase.Builder.fallbackToDestructiveMigration *方法之一进行破坏性迁移。
我尝试清除应用程序数据缓存并清除其所有数据,甚至卸载应用程序,然后使用修改后的数据库文件重新安装它。并没有解决问题。我还尝试了Room cannot verify the data integrity处的所有操作,包括在清单中设置android:allowBackup =“ false”,以及将fallbackToDestructiveMigration添加到数据库中。尝试fallbackToDestructiveMigration之后,我所有新数据库的数据都消失了。但是,然后我再次将更改后的数据库文件放回去,并且它可以正常工作。老实说,我不确定是什么步骤使它成功了。我认为这是在增加版本号,并使用fallbackToDestructiveMigration运行它,然后在fallbackToDestructiveMigration擦除了数据库中的数据后再次将新的数据库文件移回...
我的问题是,如果房间的结构没有任何变化,使其与我的应用的实体不兼容,那么Room如何知道数据库已被修改?即使我已经从设备中清除了应用程序的数据,又怎么知道呢?还有我下次没有采取的上述未提及的任何步骤吗?我问我可以包括什么都不做的迁移代码。但这似乎有点愚蠢,我希望版本号保持为1,因为该应用目前正在开发中。
答案 0 :(得分:0)
添加一个空的迁移。
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
// empty migration.
}
}
if (sInstance == null) {
if (!checkDataBase())
copyDataBase(context)
synchronized(AppDatabase::class) {
sInstance = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, DATABASE_NAME)
.addMigrations(MIGRATION_1_2)
.build()
}
}
return sInstance!!
您可以从Florina Muntenescu查看此Migration Guide,以了解有关迁移的更多信息