Android:使用Room创建的SQLite数据库在使用Sqlite Browser打开时没有显示表格

21

我正在使用Room Persistence Library 1.1.0。使用Android Studio的设备文件浏览器,我可以在/data/data/<package_name>/databases/找到数据库文件。

它包含多个表格,我可以使用room-DAO轻松访问这些表格的内容。但是,当使用sqlite-browser打开时,它没有显示任何表格。

可能的原因是什么?是否有可能不切换回从room使用旧的SQLiteOpenHelper解决此问题?

4个回答

64

解决方案

要使用 sqlite-browser 打开这种数据库,必须复制所有三个文件。所有文件都必须位于同一个目录中。关于“多文件存储”的细节请参考问题描述。


为什么需要三个文件?

根据文档,在版本 1.1.0 开始,如果设备有足够的 RAM 并且运行在 API Level 16 或更高级别上,Room 使用 write-ahead logging 作为默认日志模式。直到此版本之前,它对所有设备都是 Truncate。与 Truncate 相比,write-ahead logging 具有不同的内部结构。


现在让我们看一下 SQLite 的临时文件:

版本 1.1.0 之前:

enter image description here

版本 1.1.0 及以后:

enter image description here


如果要显式更改日志模式为 Truncate,可以使用以下方式。但不建议这样做,因为 WALTruncate 更好。

public static void initialize(Context context) {
    sAppDatabase = Room.databaseBuilder(
            context,
            AppDatabase.class,
            DATABASE_NAME)
        .setJournalMode(JournalMode.TRUNCATE).build();
}

能否在不改用Truncate的情况下将其移动到单个文件中?

可以,执行以下语句查询数据库。

pragma wal_checkpoint(full)

这里详细讨论了这里


14

从Android Studio的设备文件浏览器中将这三个文件复制到您的PC目录,然后在Db Browser for SQLite(http://sqlitebrowser.org)中打开db文件。确保这三个文件都在同一个文件夹中。


1
作为另一种选择,也有sqlitestudio https://sqlitestudio.pl/index.rvt。 - Vlad

2
您可以使用wal_checkpoint指令来触发一个checkpoint,将WAL文件中的事务移回到数据库中。
        theRoomDb.query("pragma wal_checkpoint(full)", null)

或者

        // the result
        // contains 1 row with 3 columns
        // busy, log, checkpointed
        Cursor cursor = theRoomDb.query("pragma wal_checkpoint(full)", null)

有关pragma参数值和结果的更多详细信息,请参见PRAGMA语句

如果未启用WAL,则pragma无效。 顺便说一下,我测试了Room 1.1.1,并且默认情况下未使用WAL模式,我必须启用它。


1
theRoomDb.query is not working for me without Dao - Vlad

-2

Room数据库导出和导入解决方案

我在一个项目中遇到了同样的问题,花了两天时间来解决这个问题。

解决方案

不要为Room库创建多个实例。多个实例会导致所有问题。

MyApplication

class MyApplication: Application() 
{

companion object {
    lateinit var mInstanceDB: AppDatabase
}

override fun onCreate() {
    super.onCreate()
    mInstanceDB = AppDatabase.getInstance(this)
}
}

AppDatabase

fun getInstance(context: Context): AppDatabase 
{

if (sInstance == null) {

    sInstance = Room.databaseBuilder(context.applicationContext,AppDatabase::class.java, "database").allowMainThreadQueries().build() 

            return sInstance!!
}
}

现在,您可以像这样在任何活动或片段中使用此实例

{
    var allcustomer = MyApplication.mInstanceDB.customerDao.getAll()
}

使用这个库进行导出和导入

implementation 'com.ajts.androidmads.sqliteimpex:library:1.0.0'

Github链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接