Android Room数据库文件为空 - .db、.db-shm、.db-wal

40

在Android中使用Room进行数据库操作。当我尝试在SQLViewer中查看数据时,发现数据库文件中没有表格。Myapp.db文件为空。
路径为Data/data/packageName/databases/Myapp.db。


所以你尝试查询数据库了吗?还是它们也不起作用?请包括你的数据库代码和插入/查询代码,这样人们才能帮助你。 - Suleyman
但不要在任何查看器中返回翻译后的文本。 - KKSINGLA
已经探索过了...如果我不使用Room,那么我可以在表中找到数据...但是当我使用Room时,在该文件中找不到任何数据或表。 - KKSINGLA
尝试这个 https://dev59.com/xlUL5IYBdhLWcg3wB0BJ#53976242 - Shahab Saalami
问题已解决。请使用@kosas的答案。 - KKSINGLA
显示剩余3条评论
5个回答

116

前往文件夹Data/data/packageName/databases/。这里应该有三个文件:.db.db-shm.db-wal。将这三个文件复制到一个位置,然后打开Myapp.db文件。这两个额外的文件是打开db文件所必需的。


4
相同的操作,但没有找到表格。 - KKSINGLA
1
DB浏览器对于同样的错误。文件大小仅为4KB。 - KKSINGLA
我明白了,.db-wal文件包含所有数据。 - LeTadas
2
我也尝试过了,似乎安卓工作室在保存文件时存在某种错误,因为有时它可以正常工作,但有时会显示空数据库。 我所做的是先保存三个文件,然后打开.db文件。 它为空,所以我关闭了数据库编辑器,删除了所有文件,再次保存并打开,这时它就包含了所有数据。 - LeTadas
我遇到了同样的问题,该怎么办,请建议。 - Abhishek Dubey
显示剩余5条评论

30

在Android Studio 3.1.*中:

在工具窗口栏中,点击"Device File Explorer",通常可以在屏幕右下角找到它。

打开目录:data/data/your-application-package/databases

在新的架构下,会在数据库目录中创建3个文件。

your-database-name
your-database-name-shm
your-database-name-wal

你需要将所有三个文件都导出到同一个目录中,

然后在任何sqlite浏览器中打开第一个文件(只有你的数据库名称),

现在你就可以看到所有的数据......

your-database-name-shm
your-database-name-wal

打开数据库文件需要这两个附加文件,如果你只打开数据库文件,那么在该文件中将找不到任何表。


我有同样的问题,请查看链接 - milad salimi
1
您可能需要将文件重命名为以下名称:your-database-name.dbyour-database-name.db-shmyour-database-name.db-wal - Mr-IDE

10

确保在退出应用程序时关闭数据库,这将确保所有未完成的事务都得到提交:

@Override
protected void onDestroy() {
    super.onDestroy();

    // close the primary database to ensure all the transactions are merged
    MyAppDatabase.getInstance(getApplicationContext()).close();
}

然后,您可以使用Android Studio中的设备文件浏览器(查看/data/data//databases下)将数据库从设备上复制出来。
您还可以强制进行WAL检查点而不是关闭数据库,但在我看来,这个选项更容易(除非您正在尝试在应用程序中编程备份数据库之类的操作),关闭数据库是个好主意(即使在Android Room文档中没有提到)。
在此处阅读有关sqlite WAL的更多信息:https://www.sqlite.org/wal.html

谢谢...我的根本问题是我没有复制所有三个文件。 - KKSINGLA
1
@KKSINGLA 我的解决方案意味着你不需要复制所有3个文件,这样会更容易些,在我看来。 - Dagmar
1
很好,我也会尝试这个。 - KKSINGLA
不能保证onDestroy会在您的活动中被调用,而这些文件由Room使用,因此它们始终存在,除非您设置WriteAhead,否则无法摆脱它们。 - live-love
@live-love 你必须理解问题和我的回答的背景。确实有可能使Sqlite完成所有未完成的事务,从而将所有数据从wal文件移动到主数据库文件中。这对于想要将数据从设备导出并在计算机上查看的人很有帮助。但是你是正确的 - onDestroy不能保证执行,但如果你控制一切,你可以确保它被执行。 - Dagmar

7

我保存了整个文件夹,这就可以让我浏览表格了。在此输入图片描述


1
当然它能与您一起工作,这不是偶然,而是因为需要打开原始数据库文件的其他数据库文件。请提供更准确的答案以及为什么它应该能够工作。 - blueware
@blueware,你是对的,我的错。我会尽快更新,如果可以请帮助改善答案。 - Wale

0

请检查您的数据库类。

@Database(entities = arrayOf(Test::class), version = 1, exportSchema = false)

abstract class MyDatabase:RoomDatabase() {
       private var INSTANCE: MyDatabase? = null
       abstract fun testDao(): TestDao
}

这里,MyDatabase是我的数据库类,Test是表名,TestDao是Dao类。


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