我知道这已经讨论过但我想问一下目前的情况。我是否必须创建一个ContentProvider以将CursorLoader与sqlite数据库结合使用?
我找到了
CursorLoader usage without ContentProvider
正如Emmby所评论的那样,看起来正是我所希望的
提到了另一个解决方案
https://github.com/commonsguy/cwac-loaderex
再次指出了一些缺点
当然,当使用LoaderManager时,我们希望获得它所引入的所有好处。所以我的问题是,如果有一种方法可以使用LoaderManager与sqlite数据库连接,而无需实现内容提供程序,但具有它的所有好处。
由于
答案 0 :(得分:66)
您在帖子中提到的两个实现都提供了CursorLoader
的所有好处,但能够在基础内容发生变化时接收通知。
我最近一直在研究这个问题,我可以自信地告诉你,Android API目前没有提供仅使用原始SQLiteDatabase
执行此操作的方法(它仅提供ContentResolver#notifyChange()
}和Cursor#setNotificationUri()
方法,用于通知在特定通知Cursor
下注册的所有Uri
。
那就是说,你现在的选择是:
自己实现一个能够在内容发生变化时从SQLiteDatabase
接收通知的观察者,并以某种方式将这些通知转发给应用程序中的所有现有Loader
。我写了一篇非常广泛的blog post关于如何实施Loader
如果你想接受这个挑战可能派上用场的话。或...
使用Mark Murphy的LoaderEx
库,仅使用其库提供的AsyncTask
操作进行数据库修改。请注意,他的任务刷新Loader
的原因是因为他们在执行插入/更新/删除后立即在onContentChanged
上调用Loader
,有效地告诉Loader
内容已更改,应刷新其数据。
只需将ContentProvider
与CursorLoader
一起使用,您就可以使用ContentResolver#notifyChange()
方法通知CursorLoader
内容已发生更改。
我正在试图找出一个更好的解决方案,如果我找到/实现一个,我将在未来报告,但现在这些必须要做。
答案 1 :(得分:2)
这是我的解决方案,在我的onCreateLoader
中{
Uri u = Uri.parse("content://what_string_you_want");
return new CursorLoader(this, yourURI, projection, null, null, null) {
private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
@Override
public Cursor loadInBackground() {
Cursor c = YOUR_DATABASE.doYourQuery(...);
if (c != null) {
// Ensure the cursor window is filled
c.getCount();
c.registerContentObserver(mObserver);
}
c.setNotificationUri(getContext().getContentResolver(), getUri());
return c;
}
};
}
在将更改DB的代码之后,添加
getContentResolver().notifyChange(
Uri.parse("content://same_with_first_string"), null);