为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

鸿蒙传说 2022-12-28 11:05:09
我遇到了与以下链接中的用户相同的问题。他提到仅在特定的安卓设备上创建一个空数据库(对我来说,它是像素,对他来说,是不同的安卓手机)。但是,在大多数 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
查看完整描述

2 回答

?
浮云间

TA贡献1829条经验 获得超4个赞

简而言之,如果您使用正确的技术,但如果您使用历史上经常使用的方法,则不需要,如下所示,那么您必须这样做,因为:-

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 文件也被读取和重写)。


查看完整回答
反对 回复 2022-12-28
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

我认为这个问题是由于每个 Android 版本都带来了不同的 SQLite 版本,并且一些供应商也自定义了 SQLite 库版本。正如您可以从此链接中阅读的那样:


Android API SQLite Version

API 27  3.19

API 26  3.18

API 24  3.9

API 21  3.8

API 11  3.7

API 8   3.6

API 3   3.5

API 1   3.4

希望能帮助到你。


查看完整回答
反对 回复 2022-12-28
  • 2 回答
  • 0 关注
  • 149 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号