Jellybean 中的 Android SQLite 数据库事务/锁定更改

Posted

技术标签:

【中文标题】Jellybean 中的 Android SQLite 数据库事务/锁定更改【英文标题】:Android SQLite database transaction/locking changes in Jellybean 【发布时间】:2013-04-26 22:53:01 【问题描述】:

我有一个 SQLite 数据库,它在我的应用程序中得到了大量使用。访问地址:

各种活动,通过 ASyncTasks 将数据加载到 UI 中(仅限 select 语句) 多个后台进程(一次只能运行其中一个),它们执行许多插入/更新

我调用一次 getWritableDatabase() 并在任何地方使用它。每个后台进程都使用 IMMEDIATE(即非锁定)事务,这会将其中一些进程从几分钟缩短到几秒钟。

这一切都在 Jellybean 之前完美运行;后台进程具有事务的速度优势,但这并没有阻止 Activites 通过 ASyncTasks 加载数据。

在 Jellybean 之后,每个用于 GUI 的 ASyncTask 加载数据在事务进行时都会被阻止,因此通常会在几秒钟内不返回。这使得导航缓慢而令人沮丧。我已将阻塞隔离到 rawQuery 数据库调用。

除了不推荐使用的几种方法 - http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#isDbLockedByOtherThreads() - 使用像 这样的 cmets 之外,我找不到任何文档可以准确说明 Jellybean 中发生的变化“不再有数据库锁的概念,所以这个方法总是返回 false。”

有没有一种简单的方法来模仿前果冻豆的行为?

【问题讨论】:

【参考方案1】:

似乎 Jelly Bean 之前的异步任务一直在并行运行。现在你已经有了一个 Executor 来串行运行异步任务。好消息是,您可以通过基于操作系统版本的分支来指定任务的运行方式。

阅读this article

【讨论】:

谢谢,但我已经将 AsyncTask.THREAD_POOL_EXECUTOR 用于 ICS 及更高版本。在这种情况下,日志记录将 rawQuery 调用隔离为阻止程序。【参考方案2】:

我找到了解决我自己问题的方法。 我仍然不确定 Google 在 Jellybean 中究竟做了什么改变,以停止现在工作之前的工作 - 但解决方案是使用 enableWriteAheadLogging()。

我之前尝试过,但无济于事 - 在事务进行时,我仍然收到阻塞读取。对我来说重要的一点是(在 enableWriteAheadLogging() 文档中)

如果数据库有任何附加的数据库,则无法并行执行查询。

不幸的是,我的应用程序有两个独立的数据库,它们连接在一起以允许联合查询 - enableWriteAheadLogging() 返回 false。我已经制作了移除附件的原型,这解决了阻塞问题;当另一个线程运行即时事务时,我的选择查询都会立即运行。

遗憾的是,我将不得不重新设计我的数据库架构以实施完整的修复。

【讨论】:

以上是关于Jellybean 中的 Android SQLite 数据库事务/锁定更改的主要内容,如果未能解决你的问题,请参考以下文章

Sencha Touch/Cordova 应用程序在 HTC One 中的 Android Level 18 Jellybean 4.3 更新后遭到破坏

Android 4.3 Jelly Bean 中的打印支持

更改 Android JellyBean 上的操作栏高度

run-as 包 'a.b.c' 未知 - Galaxy S4 Jellybean 或 Android 4.3

Android WebView JellyBean -> 不应该发生:找不到基于矩形的测试节点

有没有办法在 Android JellyBean TimePickerDialog 中使用取消?