为什么我需要在设置 this.getReadableDatabase() 后关闭数据库?

我遇到了与以下链接中的用户相同的问题。他提到仅在特定的安卓设备上创建一个空数据库(对我来说,它是像素,对他来说,是不同的安卓手机)。但是,在大多数 Android 手机上,代码中的当前行为有效。

发布了一个解决方案,其中有人提到要在解决问题db.close()后添加。this.getReadableDatabase()但是,我不确定为什么会修复它以及为什么该行为仅适用于某些 Android 设备?

这是链接: http ://www.anddev.org/networking-database-problems-f29/missing-table-in-sqlite-with-specific-version-of-desire-hd-t50364.html


鸿蒙传说
浏览 151回答 2
2回答

浮云间

简而言之,如果您使用正确的技术,但如果您使用历史上经常使用的方法,则不需要,如下所示,那么您必须这样做,因为:-this.getReadableDatabase()使用/已经使用的原因是在 data/data/the_package/ 目录中创建数据库文件夹/目录。如果数据库目录不存在,则来自资产的典型副本将失败并出现 ENOENT 错误。SQLite 默认使用日志模式日志记录,这不是问题,因此历史上 using的绕过方法this.getReadableDatabase()一直有效。但是,在 Android Pie (28) 中,SDK 已更改为默认使用预写日志记录 (WAL),这是一种较晚且更高级的日志记录方法。此方法使用两个已改进安全措施的文件。一个是文件被标记/标记为属于创建它们的数据库。因此,当使用没有关闭的旧方法复制数据库时,这两个文件(数据库文件以 -wal 和 -shm 为后缀)存在并且很可能包含日志记录数据(例如任何表的创建)。但是,它们不会被标记为用于复制的数据库,因此(我相信)重新创建数据库(因为复制的数据库由于数据库与 -shm 和 -wal 文件不匹配而无法打开)因此随后的表未找到通常会遇到的错误。使用 WAL 关闭数据库/连接会导致数据被提交,因此为什么在this.getReadableDatabase()工作后(立即)关闭数据库。但是,正确的解决方法是使用 File 方法检查并创建数据库目录(如果它不存在)。这样就不需要打开数据库,这会浪费资源,也不需要关闭数据库,这也会浪费资源(即实际执行记录的操作并将数据写入磁盘和 -wal 和-shm 文件也被读取和重写)。

元芳怎么了

我认为这个问题是由于每个 Android 版本都带来了不同的 SQLite 版本,并且一些供应商也自定义了 SQLite 库版本。正如您可以从此链接中阅读的那样:Android API SQLite VersionAPI 27  3.19API 26  3.18API 24  3.9API 21  3.8API 11  3.7API 8   3.6API 3   3.5API 1   3.4希望能帮助到你。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java