异步Android SQLite数据库的正确实现
Posted
技术标签:
【中文标题】异步Android SQLite数据库的正确实现【英文标题】:Correct implementation of asynchronous Android SQLite database 【发布时间】:2016-03-23 08:59:36 【问题描述】:我搜索了一下,发现了多种异步访问本地 SQLite 数据库的方法:
异步任务 CursorLoader(我已经使用它进行查询以检索我的联系人信息,但我不确定这将如何转换为具有多个查询的 SQLiteOpenHelper 子类) ContentProvider - 不确定它是否过度,数据库将只需要在应用程序内最佳做法是什么?我目前有一个 SQLiteOpenHelper 子类,其中包含基本的表创建/升级/等。逻辑。
【问题讨论】:
你是在说只读操作(查询),还是写操作(插入、更新、删除)? 读写操作。 【参考方案1】:CursorLoader
仅支持查询。如果您在 UI 中显示数据,您可能仍想使用它并利用 Loader 框架。 CursorLoader
旨在与 ContentProvider
一起使用,但您可以复制源代码并对其进行修改以采用 SQLiteDatabase 而不是 Context 并在 loadInBackground()
方法内查询数据库而不是 ContentResolver
。
对于写操作,您有几个选项需要考虑(这些选项并不相互排斥,您最终可能会根据情况使用多个选项):
异步任务 处理程序 意图服务 异步查询处理程序 Java 线程/执行器框架我通常将AsyncTask
用于可能对 UI 产生轻微影响的一次性操作(例如,在屏幕上显示和隐藏某些指示器)。请注意,AsyncTasks 在单个工作线程上串行运行,除非您将自己的 Executor 提供给 execute()
。
IntentService
很有用,因为它将所有启动命令排队并在工作线程上串行执行,并在完成所有命令后自动关闭。它是一项服务,因此它与任何活动/UI 组件分开运行,但这也意味着存在一些开销,因为它是一个需要由系统创建和启动的应用程序组件。我喜欢它们用于批处理操作或将来某个时间安排的操作。
AsyncQueryHandler
不仅仅是查询(尽管它是如何命名的),但就像CursorLoader
它希望您与ContentProvider
通信。您可以使用一个来处理不同类型的操作。需要注意的是,ContentProvider
本身不提供异步处理,您必须从后台线程调用它,这正是 AsyncQueryHandler
所做的。
最后,良好的旧 Java 线程和执行器框架工作得很好,尽管您可能希望有某种应用程序组件供它们运行(可能是服务,但如果是这种情况,您可能会选择IntentService 无论如何都在上面)。
【讨论】:
感谢您的回复,我发现它非常有帮助。但是,仍然有一些事情困扰着我:AsyncQueryHandler 似乎无法进行批量插入。这对我来说有点问题,因为我想在数据库中插入几百条记录。在那种情况下,getContentResolver().applyBatch 会更适合这项工作吗? (我假设这将在 UI 线程上运行)。还是我应该通过 AsyncQueryHandler 调用 startInsert 几百次?看起来 IntentService 子类毕竟不是一个坏主意......【参考方案2】:CursorLoader
仅用于异步读取数据
ContentProvider
是为其他应用提供数据,没有同步或异步访问的选项。
我建议你使用AsyncTask
【讨论】:
这是不正确的。 ContentProvider 也可以为您自己的应用程序提供数据。 @Karakuri 请阅读文档:developer.android.com/reference/android/content/…“仅当您需要在多个应用程序之间共享数据时才需要内容提供程序。” 我已经构建了至少六个使用 ContentProvider 的应用程序,其中大多数不与其他应用程序共享数据。不需要它并不意味着你不能使用它。以上是关于异步Android SQLite数据库的正确实现的主要内容,如果未能解决你的问题,请参考以下文章
ANDROID_MARS学习笔记_S04_002_用AsyncTask实现异步操作
android sqlite3命令行检查自己的代码操作数据库是否正确