[英]Intercepting room migration errors to recreate the DB
在https://medium.com/google-developers/understanding-migrations-with-room-f01e04b07929上有一篇有關會議室遷移的精彩文章。
但是,我仍然錯過Room中的“災難”恢復機制(例如fallbackToDestructiveRecreationOnMigrationError()會在發生奇怪的情況時清除並重新創建數據庫)
這是我們發生的事情:
一個開發人員通過遷移推送了版本9,但是架構9.json不符合要求(我怎么可能不知道)=>房間做了遷移並且沒有錯誤。
然后,當我們提供版本10時,文件9.json已更改=>房間崩潰了,用戶再也無法訪問該應用程序了(這很正常)。
我們必須告訴用戶擦除他們的數據(這不是技術問題,因為我們在應用啟動時重新同步了數據庫,但這是一個公共關系問題)
我認為應該可以在構建器中使用openHelperFactory,但這對我來說很不深入房間內部:(
經過無數次嘗試和絕望,這是我使用的解決方案:
abstract class MainDatabase: RoomDatabase() {
companion object {
val instance: MainDatabase by lazy {
if (_instance == null) throw IllegalStateException("someone should have called init fun")
_instance!!
}
private var _instance: MainDatabase? = null
fun init(mainApplication: MainApplication) {
_instance = init_(mainApplication)
//force db opening and if it fails, we try to destroy and recreate the db
try {
_instance!!.openHelper.writableDatabase
} catch (e: Exception) {
Log.e("Database", "there was an error during DB opening => trying to destroy and recreate", e)
_instance!!.openHelper.close()
val dbPath = mainApplication.getDatabasePath(DB_NAME)
if (SQLiteDatabase.deleteDatabase(dbPath)) {
_instance = init_(mainApplication)
_instance!!.openHelper.writableDatabase
}
}
}
private fun init_(mainApplication: MainApplication): MainDatabase {
return Room.databaseBuilder(mainApplication, MainDatabase::class.java, DB_NAME)
.addMigrations(MIGRATION_1, MIGRATION_2, MIGRATION_3, MIGRATION_4, MIGRATION_5, MIGRATION_6, MIGRATION_7, MIGRATION_8, MIGRATION_9, MIGRATION_10)
.build()
}
}
該解決方案的真正缺點是,對db的首次訪問是在主線程上完成的。
如果有人有更好的解決方案,請分享!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.