异步androidsqlite数据库的正确实现

异步androidsqlite数据库的正确实现,android,sqlite,android-asynctask,android-contentprovider,Android,Sqlite,Android Asynctask,Android Contentprovider,我在谷歌上搜索了一下,发现了多种异步访问本地SQLite数据库的方法: 异步任务 CursorLoader(我已经将其用于查询来检索我的联系人信息,但我不确定如何将其转换为具有多个查询的SQLiteOpenHelper子类) ContentProvider-不确定是否过度使用,只需要从应用程序内部使用数据库 最佳做法是什么?我目前有一个SQLiteOpenHelper子类,它包含基本的表创建/升级/等逻辑。 CursorLoader仅用于异步读取数据 ContentProvider是向其他应

我在谷歌上搜索了一下,发现了多种异步访问本地SQLite数据库的方法:

  • 异步任务
  • CursorLoader(我已经将其用于查询来检索我的联系人信息,但我不确定如何将其转换为具有多个查询的SQLiteOpenHelper子类)
  • ContentProvider-不确定是否过度使用,只需要从应用程序内部使用数据库
最佳做法是什么?我目前有一个SQLiteOpenHelper子类,它包含基本的表创建/升级/等逻辑。

  • CursorLoader
    仅用于异步读取数据
  • ContentProvider
    是向其他应用程序提供数据,没有同步或异步访问的选项

我建议您使用
AsyncTask

CursorLoader
仅支持查询。如果在UI中显示数据,您可能仍然希望使用它并利用Loader框架
CursorLoader
旨在与
ContentProvider
一起使用,但您可以复制源代码并将其修改为使用SQLiteDatabase而不是上下文,并在
loadInBackground()
方法内查询数据库而不是
ContentResolver

对于写操作,你有几个选项要考虑(这些不是互斥的,你可能会根据情况而使用不止一个):

  • 异步任务
  • 处理者
  • 意向服务
  • 异步查询处理器
  • Java线程/执行器框架
我通常使用
AsyncTask
进行一次性操作,这些操作可能会对UI产生轻微影响(例如,在屏幕上显示和隐藏某些指示器)。请注意,异步任务在单个工作线程上串行运行,除非您向
execute()
提供自己的执行器

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

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


最后,好的旧Java线程和executor框架工作得很好,尽管您可能希望有某种应用程序组件让它们运行(可能是服务,但如果是这样的话,您可能只需要使用上面的IntentService)。

您说的是只读操作(查询),还是写操作(插入、更新、删除)?读取和写入操作。这是不正确的。ContentProvider也可以为您自己的应用程序提供数据。@Karakuri请阅读文档:“只有当您需要在多个应用程序之间共享数据时,才需要内容提供程序。”我已经构建了至少六个使用ContentProvider的应用程序,其中大多数都没有与其他应用程序共享数据。仅仅因为它不是必需的,并不意味着你不能使用它。感谢你的回复,我发现它非常有帮助。然而,仍然有一些问题困扰着我:AsyncQueryHandler似乎没有能力f批插入。这对我来说有点问题,因为我想在数据库中插入几百条记录。在这种情况下,getContentResolver().applyBatch是否更适合该作业?(我假设这将在UI线程上运行).或者我应该通过AsyncQueryHandler调用startInsert几百次吗?看来IntentService子类毕竟不是个坏主意。。。