重新打开房间数据库 [英] Reopen ROOM database

查看:30
本文介绍了重新打开房间数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试关闭,然后重新打开Room数据库。(目的是备份SQLite文件)

我是这样关闭它的:

public static void destroyInstance() {
    if (INSTANCE != null && INSTANCE.isOpen()) {
        INSTANCE.close();
    }
    INSTANCE = null;
}

实例是RoomDatabase对象

要重新打开,我正在通过调用以下命令再次初始化实例对象:

Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, C.ROOM_DB_NAME)

转到另一个活动后,我在logcat中看到此错误:E/ROOM: Invalidation tracker is initialized twice

SELECT查询工作正常,但插入失败,出现以下错误:

E/SQLiteLog: (1) no such table: room_table_modification_log

E/ROOM: Cannot run invalidation tracker. Is the db closed?
java.lang.IllegalStateException: The database '/data/user/0/ro.example.example/databases/mi_room.db' is not open.

虽然INSTANCE.isOpen()返回TRUE

房间版本:1.1.1

有人知道这个"ROOM_TABLE_MODIFICATION_LOG"表是怎么回事吗?

推荐答案

对于将来的读者:您不需要关闭数据库即可将文件复制到其他位置(创建备份)。

SQLite数据库的Android实现通常为WAL(write-ahead log)模式。这在后台使用3个文件:第一个文件带有数据库的名称(即my_db),第二个文件带有该名称和"-shm"后缀(my_db-shm),第三个文件带有"-wal"后缀(my_db-wal)。-wal文件将保存更改。

如果要使用数据库(my_db文件)的普通路径进行备份,则需要确保它是最新的事务。您可以通过在数据库上运行检查点来执行此操作。在此之后,您可以将此文件复制到电话上的所需位置,然后继续使用您的数据库,而不会出现问题。this question上的公认答案很好地解释了这一点:

但是,如果将所有内容都移动到原始数据库文件 想要这样做,那么您就不必关闭数据库了。

您可以强制 检查点,请改用wal_checkpoint杂注。查询 下面是针对数据库的语句。我们在这里使用原始查询 由于房间暂不支持pragma(会触发UNKNOWN query type error)。

将此查询放在DAO中:

@RawQuery
int checkpoint(SupportSQLiteQuery supportSQLiteQuery);

然后当您 调用检查点方法,然后使用查询:

myDAO.checkpoint(new SimpleSQLiteQuery("pragma wal_checkpoint(full)"));

这篇关于重新打开房间数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆