54

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

我发现

没有 ContentProvider 的 CursorLoader 使用

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

  • 用户应该知道一个限制,那就是它没有刷新数据更改的机制(就像加载器应该做的那样)

所以提到了另一种解决方案

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

再次指出了一些缺点

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

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

谢谢

4

3 回答 3

66

您在帖子中提到的两种实现都提供了所有的好处,CursorLoader 除了当底层内容发生变化时接收通知的能力。

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

也就是说,您现在的选择是:

  1. 自己实现一个观察者,它能够SQLiteDatabase在内容更改时接收通知,并且能够以某种方式将这些通知中继到Loader应用程序中的所有现有 s。我写了一篇关于如何实现s的相当广泛的博客文章Loader,如果你想接受这个挑战,它可能会派上用场。或者...

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

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

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

于 2012-10-13T02:58:57.323 回答
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;
    }
};
}

在将更改数据库的代码之后,添加

 getContentResolver().notifyChange(
            Uri.parse("content://same_with_first_string"), null);
于 2014-12-09T17:25:16.227 回答
0

将共享首选项中的布尔值设置为假怎么样..当该布尔值为真时更新内容..以及当任何更改底层数据库的操作时..该布尔值将设置为真并作为共享首选项您changelistener 您可以在调用相关方法后直接接收更改

于 2021-08-25T15:59:14.987 回答