问题描述
我在Google周围搜索,发现了多种异步访问本地SQLite数据库的方法:
I've Googled around and have found multiple ways of accessing a local SQLite database asynchronously:
- AsyncTask
- CursorLoader(我已经在查询中使用它来检索我的联系人信息,但是我不确定如何将其转换为具有多个查询的SQLiteOpenHelper子类)
- ContentProvider-不确定是否过大,仅需要从应用程序内部获取数据库
最佳做法是什么?我目前有一个SQLiteOpenHelper子类,其中包含基本的表创建/升级/等.逻辑.
What is the best practice? I currently have a SQLiteOpenHelper subclass which contains the basic table creation/upgrade/etc. logic.
推荐答案
CursorLoader
仅支持查询.如果要在UI中显示数据,则可能仍要使用它并利用Loader框架. CursorLoader
旨在与ContentProvider
一起使用,但是您可以复制源代码并对其进行修改,以使用SQLiteDatabase代替Context,并在loadInBackground()
方法内查询数据库而不是ContentResolver
.
CursorLoader
only supports queries. You may still want to use it and leverage the Loader framework if you are displaying data in your UI. CursorLoader
is intended to be used with a ContentProvider
, but you can instead copy the source code and modify it to take an SQLiteDatabase instead of a Context and query the database instead of a ContentResolver
inside the loadInBackground()
method.
对于写操作,您需要考虑几个选项(这些选项不是互斥的,根据情况您可能最终使用多个选项):
For write operations, you have several options to consider (these are not mutually exclusive, you may end up using more than one depending on the situation):
- AsyncTask
- 处理程序
- IntentService
- AsyncQueryHandler
- Java线程/执行程序框架
我通常将AsyncTask
用于一次可能会对UI产生较小影响的一次性操作(例如,在屏幕上显示和隐藏一些指示器).请注意,除非您为execute()
提供自己的执行器,否则AsyncTasks会在单个工作线程上串行运行.
I typically use AsyncTask
for one-off operations that may have minor UI implications (e.g. showing and hiding some indicator on screen). Note that AsyncTasks run serially on a single worker thread, unless you supply your own Executor to execute()
.
IntentService
很有用,因为它会将所有启动命令排队,并在工作线程上串行执行它们,并在完成所有启动命令后自动关闭.它是一项服务,因此它与任何Activity/UI组件均独立运行,但这也意味着存在一些开销,因为它是需要由系统创建和启动的应用程序组件.我喜欢它们用于批处理操作或将来某个时间计划的操作.
IntentService
is useful in that it queues all of its start commands and executes them serially on a worker thread, and automatically shuts down when finished with all of them. It's a Service, so it runs separately from any Activities/UI components, but that also means there's some overhead since it is an application component that needs to be created and started by the system. I like them for batch operations or operations that are scheduled sometime in the future.
AsyncQueryHandler
不仅执行查询(尽管其命名方式),而且还像CursorLoader
一样希望您正在与ContentProvider
通信.您可以使用一个来处理不同种类的操作.重要的是要注意,ContentProvider
本身并不提供异步处理,您必须从后台线程调用它,而AsyncQueryHandler
就是这样做.
AsyncQueryHandler
does more than just queries (despite how it's named), but like CursorLoader
it expects you are communicating with a ContentProvider
. You can use a single one to process different kinds of operations. It's important to note that ContentProvider
by itself does not provide asynchronous processing, you have to call it from a background thread, which is what AsyncQueryHandler
does.
最后,良好的旧Java线程和executor框架可以正常工作,尽管您可能希望有某种应用程序组件可以在其中运行(可能是Service,但如果是这种情况,则可以使用)无论如何,都是IntentService.
Finally, good old Java threading and the executor framework works just fine, though you'll probably want to have some kind of application component for them to run in (likely a Service, but if that's the case you might just go with IntentService above anyway).
这篇关于正确实现异步Android SQLite数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!