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

标签 java android sqlite

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

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

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

最佳答案

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

使用this.getReadableDatabase()的原因是在data/data/the_package/目录中创建数据库文件夹/目录。如果数据库目录不存在,则 Assets 的典型复制将失败并出现 ENOENT 错误。

对于默认使用日志模式日志记录的 SQLite,这不是问题,因此历史上使用 this.getReadableDatabase()解决方法是有效的。

但是,在 Android Pie (28) 中,SDK 已更改为默认使用预写日志记录 (WAL),这是一种较晚且更高级的日志记录方法。此方法使用两个已改进安全措施的文件。一是文件被标记/标记为属于创建它们的数据库。

因此,当使用旧方法复制数据库而不关闭时,两个文件(后缀为 -wal 和 -shm 的数据库文件)存在,并且很可能包含日志数据(例如任何表的创建)。但是,它们不会被标记为用于复制的数据库,因此(我相信)会重新创建数据库(因为由于数据库与 -shm 和 -wal 文件之间不匹配而无法打开复制的数据库),因此随后通常会遇到找不到表错误。

通过 WAL 关闭数据库/连接会导致数据被提交,因此为什么要在 this.getReadableDatabase() 工作后(立即)关闭数据库。

但是,正确的修复方法是使用 File 方法检查并创建数据库目录(如果不存在)。这样就不需要打开数据库,这会浪费资源,也不需要关闭数据库,这也会浪费资源(即实际执行记录的操作并将数据写入磁盘,并且 -wal 和-shm 文件也会被读取和重写)。

关于java - 为什么我设置 this.getReadableDatabase() 后需要关闭数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56417566/

相关文章:

java - 如何使用 Spring Boot 指定 BeanNamingStrategy?

android - 创建具有 5 种不同颜色的自定义栏

java - Android中的SQLite如何更新特定行

java - Content-Length 分隔的消息正文过早结束(预期为 :

javascript - 在浏览器中检查 JRE 版本

java - 无法在 super 账本结构中调用链码

android - 通过蓝牙发送多个文件

php - 设备上的 android 应用程序连接到 php 脚本

ruby-on-rails - 我想将字符串和数组数据放入Ruby on Rails中的sqlite3中

python - 如何选择 sqlite3 数据库的所有行,这些行的列中包含某个变量子字符串?