正确实现异步Android SQLite数据库

Correct implementation of asynchronous Android SQLite database

我用 Google 搜索了一下,找到了多种异步访问本地 SQLite 数据库的方法:

最佳做法是什么?我目前有一个包含基本 table creation/upgrade/etc 的 SQLiteOpenHelper 子类。逻辑。

  • CursorLoader只针对异步读取数据
  • ContentProvider是给其他应用程序提供数据,没有同步或异步访问的选项。

我建议你使用AsyncTask

CursorLoader 只支持查询。如果您要在 UI 中显示数据,您可能仍想使用它并利用 Loader 框架。 CursorLoader 旨在与 ContentProvider 一起使用,但您可以复制源代码并修改它以采用 SQLiteDatabase 而不是 Context 并查询数据库而不是内部的 ContentResolver loadInBackground() 方法。

对于写入操作,您有多种选择可供考虑(这些并不相互排斥,您最终可能会根据情况使用多种选择):

  • 异步任务
  • 处理程序
  • 意图服务
  • AsyncQueryHandler
  • Java threading/executor 框架

我通常使用 AsyncTask 进行一次性操作,这些操作可能具有较小的 UI 影响(例如,在屏幕上显示和隐藏某些指示器)。请注意,AsyncTasks 运行 在单个工作线程上串行执行,除非您向 execute().

提供自己的执行器

IntentService 很有用,因为它将所有启动命令排队并在工作线程上连续执行它们,并在完成所有这些命令后自动关闭。它是一个服务,因此它 运行 与任何 Activities/UI 组件分开,但这也意味着有一些开销,因为它是一个需要由系统创建和启动的应用程序组件。我喜欢它们用于批处理操作或安排在将来某个时间的操作。

AsyncQueryHandler 不仅仅是查询(尽管它的命名方式),但像 CursorLoader 一样,它希望您与 ContentProvider 进行通信。您可以使用一个来处理不同类型的操作。重要的是要注意 ContentProvider 本身不提供异步处理,您必须从后台线程调用它,这就是 AsyncQueryHandler 所做的。

最后,好的旧 Java 线程和执行器框架工作得很好,尽管您可能希望为它们提供某种应用程序组件 运行 在(可能是服务,但如果是这种情况,您可能还是会使用上面的 IntentService)。