Room DB file import error (#39;no such table: room_table_modification_log#39;)(房间DB文件导入错误(#39;没有这样的表:ROOM_TABLE_MODIFICATION_LOG#39;))
问题描述
我正在尝试让我的应用程序备份和还原其DB文件(例如mydatabase ase.db)(&;Restore)。备份运行良好-它导出单个.db文件。它不会导出-shm/-wal文件,因为我运行了一个‘杂注WAL_CHECKPOINT(FULL)’来刷新对主文件的任何更新。 还原似乎运行正常,但之后当我的应用查询新复制的数据时,我收到此错误(但应用不会崩溃)。
E/ROOM: Invalidation tracker is initialized twice :/.
E/SQLiteLog: (1) no such table: room_table_modification_log
E/ROOM: Cannot run invalidation tracker. Is the db closed?
android.database.sqlite.SQLiteException: no such table: room_table_modification_log
如果我随后尝试更新任何数据,则会收到以下两个错误(现在应用程序确实崩溃了):
java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
...
E/ROOM: Cannot run invalidation tracker. Is the db closed?
android.database.sqlite.SQLiteException: no such table: room_table_modification_log (code 1 SQLITE_ERROR):
如果我关闭我的应用程序,然后重新启动它,一切都运行正常,并且可以毫无错误地查询/更新新数据。我使用的是Room 2.2.5,在我的不同设备(Android 6和10)上看到此错误。
我下面的代码。我在执行还原之前关闭数据库,否则应用数据库不会更新。
private void dbImport() {
// DB Backup file to import (e.g. mydatabasebackup.db)
final Uri backupFile = viewModel.getDBImportFile();
String internalDBFile = context.getDatabasePath(APP_DATABASE_NAME).toString();
// Close app database
MyDatabase.destroyInstance();
restoreDatabase(backupFile, internalDBFile);
}
private void restoreDatabase(Uri backupFile, String internalDBFile) {
InputStream inputStream = context.getContentResolver().openInputStream(backupFile);
OutputStream outputStream = new FileOutputStream(internalDBFile);
// Copy backup -> DB
byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
inputStream.close();
// Write the output file (this has now copied the file)
outputStream.flush();
outputStream.close();
}
和My Room DB类
public abstract class MyDatabase extends RoomDatabase {
private static MyDatabase DB_INSTANCE;
public static MyDatabase getDatabase(final Context context) {
if (DB_INSTANCE == null) {
synchronized (MyDatabase.class) {
if (DB_INSTANCE == null) {
DB_INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
MyDatabase.class, APP_DATABASE_NAME)
.addMigrations(new Migration_1_2(context, 1, 2))
.build();
}
}
}
return DB_INSTANCE;
}
public static void destroyInstance() {
if (DB_INSTANCE != null) {
if (DB_INSTANCE.isOpen()) {
DB_INSTANCE.close();
}
DB_INSTANCE = null;
}
}
推荐答案
回答我自己的问题,以防其他人遇到同样的问题。
我在BackupActivity中导入DB文件,一旦完成,它将返回到MainActivity(它查询数据库并显示数据)。回到MainActivity,我重新创建了我的LiveData观察器,并再次重新运行我的DB查询,以便从新导入的数据库中获取数据。问题似乎是我没有为新数据库重新创建回购/DAO。由于IF/NULL检查,ViewModel仍保留以前的回购引用。
ViewModel
LiveData<User> userLD = getUserRepo().getUser();
private UserRepo getUserRepo() {
if (userRepo == null) {
userRepo = new UserRepo(getApplication());
}
return userRepo;
}
用户回购
// Constructor
public UserRepo(Application application) {
super();
MyDatabase db = MyDatabase.getDatabase(application);
dao = db.getUserDao();
}
通过重新创建UserRepo(取消IF/NULL检查),新的Repo/DAO基于新的DB,现在一切正常。
另一个同样有效的解决方案是,在执行DB导入之后从BackupActivity返回时,我使用这些标志从头重新启动MainActivity(以完成堆栈中的所有活动-包括BackupActivity)。
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
这篇关于房间DB文件导入错误(';没有这样的表:ROOM_TABLE_MODIFICATION_LOG';)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:房间DB文件导入错误(';没有这样的表:ROOM_TABLE_MODIFICATION_LOG';)
基础教程推荐
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01