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

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
希望能帮助到你。
添加回答
举报