android - CursorLoader&没有Content Provider的SQLite

时间:2012-10-13 02:16:45

标签: android sqlite android-contentprovider android-loadermanager

我知道这已经讨论过但我想问一下目前的情况。我是否必须创建一个ContentProvider以将CursorLoader与sqlite数据库结合使用?

我找到了

CursorLoader usage without ContentProvider

正如Emmby所评论的那样,看起来正是我所希望的

  • 用户应该知道一个限制,即它没有机制来刷新数据更改(正如装载程序应该这样做)。

提到了另一个解决方案

https://github.com/commonsguy/cwac-loaderex

再次指出了一些缺点

  • 但是,要使用自动重新查询,您需要为UI和更新使用相同的加载程序,从而限制其对后台服务的可用性。

当然,当使用LoaderManager时,我们希望获得它所引入的所有好处。所以我的问题是,如果有一种方法可以使用LoaderManager与sqlite数据库连接,而无需实现内容提供程序,但具有它的所有好处。

由于

2 个答案:

答案 0 :(得分:66)

您在帖子中提到的两个实现都提供了CursorLoader 的所有好处,但能够在基础内容发生变化时接收通知。

我最近一直在研究这个问题,我可以自信地告诉你,Android API目前没有提供仅使用原始SQLiteDatabase执行此操作的方法(它仅提供ContentResolver#notifyChange() }和Cursor#setNotificationUri()方法,用于通知在特定通知Cursor下注册的所有Uri

那就是说,你现在的选择是:

  1. 自己实现一个能够在内容发生变化时从SQLiteDatabase接收通知的观察者,并以某种方式将这些通知转发给应用程序中的所有现有Loader。我写了一篇非常广泛的blog post关于如何实施Loader如果你想接受这个挑战可能派上用场的话。或...

  2. 使用Mark Murphy的LoaderEx库,仅使用其库提供的AsyncTask操作进行数据库修改。请注意,他的任务刷新Loader的原因是因为他们在执行插入/更新/删除后立即在onContentChanged上调用Loader,有效地告诉Loader内容已更改,应刷新其数据。

  3. 只需将ContentProviderCursorLoader一起使用,您就可以使用ContentResolver#notifyChange()方法通知CursorLoader内容已发生更改。

  4. 我正在试图找出一个更好的解决方案,如果我找到/实现一个,我将在未来报告,但现在这些必须要做。

答案 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);