我浏览了许多在 Android 中使用 SQLite 的示例/教程。假设您有一个使用 SQLite、ContentProvider
、CursorLoader
和自定义 CursorAdapter
的应用。
现在,我发现的所有主要示例都依赖于 CursorLoader
将数据提取到 CursorAdapter
,这是 CursorLoader
的本质以 Async - UI 线程安全的方式。但是,这些相同的示例都通过主线程上的 ContentResolver
进行插入/删除/更新调用(例如来自 onClick
、onResume
、onPause
). ( Example ) 它们不会将这些调用包装在 AsyncTask
中,也不会启动单独的线程或使用 AsyncQueryHandler
。
这是为什么呢,那么多写得很好的博客/例子怎么会犯这么明显的错误呢?还是简单的单行插入/删除/更新调用如此之快,以至于它们足够安全,可以从主/UI 线程启动?执行这些快速调用的正确方法是什么?
最佳答案
我也对在主线程上进行调用的示例感到困惑。我猜这些示例只是简化了演示,避免了额外的线程和回调,因为单个插入/更新/删除调用可能会快速返回。
除了用于查询的 Loader 模式之外,android 确实提供了一个辅助类 AsyncQueryHandler,从 API 级别 1 开始,用于支持完整 CRUD 回调的异步 CRUD 操作。 AsyncQueryHandler 在内部使用 HandlerThread 进行异步操作,并将结果返回到主线程。
所以我相信 ContentProvider 查询应该在 UI 以外的工作线程中运行,根据官方设计,这些示例可能不是最佳实践。
===编辑
从官方框架文档中找到注释,参见this或 this , 第 255 行:
In practice, this should be done in an asynchronous thread instead of
on the main thread. For more discussion, see Loaders. If you are not
just reading data but modifying it, see {@link android.content.AsyncQueryHandler}.
=== 编辑 2 Link到包含上述引用的实际 android 开发指南
关于Android - SQLite ContentResolver 在 UI 线程上插入/删除/更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26584568/