CursorLoader在数据更改后没有更新

49

我创建了一个小应用程序,尝试理解 LoaderManagerCursorLoader 类的功能。

我在我的 FragmentActivity 类上实现了 LoaderCallbacks<Cursor>,一切都正常工作,除了当我通过 ContentResolver.update()ContentResolver.insert() 方法更新数据时,onLoadFinished() 不会被调用,导致我的数据没有更新。

我有一个自定义的 ContentProvider,我想知道问题是不是出在我的 ContentProvider 上,即它没有通知数据已更改或者其他原因。


6
你在你的update/insert ContentProvider方法实现中调用了getContext().getContentResolver().notifyChange(Uri,..);吗?你在从query方法返回cursor之前调用了cursor.setNotificationUri(getContext().getContentResolver(), uri);吗? - Selvin
不,我没有这样做,那就是问题所在!谢谢! :) - akalipetis
3个回答

105

ContentProvider.query()返回Cursor之前,您是否调用了setNotificationUri(ContentResolver cr, Uri uri)

在您的ContentProvider的'insert'方法中,您是否调用了getContext().getContentResolver().notifyChange(uri, null)

编辑:

要获取ContentResolver,请在您的ContentProvider中调用getContext().getContentResolver()


5
我很烦恼,在按照Android开发文档创建内容提供程序时,它没有提到这一点。 - Blundell
23
同时,在onLoadFinished中的任何时候都不应该调用cursor.close(),否则您将无法接收到底层数据集的进一步更新。 - Dororo
1
setNotificationUri() 中传递的 URI 是否必须与 notifyChange() 的 URI 完全匹配,还是只需要具有相同的权限或类似的内容即可? - reubenjohn
1
URI必须相等。 - thaussma
1
@Herrmann 请问还有什么需要注意的吗?即:我使用相同的URI调用setNotificationUri(ContentResolver cr, Uri uri)和notifyChange(uri, null)。但是我的列表视图没有更新。 - f470071
显示剩余5条评论

5

同时请检查是否在某处调用了cursor.close(),因为在这种情况下,您会注销由CursorLoader注册的内容观察器。而且,关闭游标是由CursorLoader管理的。


这是我实现中缺失的关键。 - Nicolás Carrasco-Stevenson

4

接受的答案有点棘手,所以我写下这个答案,让其他开发者更容易理解。

  1. 进入您已扩展ContentProvider的类
  2. 找到具有以下语法的query()方法

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

  3. 在返回游标的位置编写此行代码

    cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor;

最后,我的查询方法如下所示:

@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

    Cursor cursor;
    cursor = noticeDbHelper.getReadableDatabase().query(
            NoticeContract.NoticeTable.TABLE_NAME,
            projection,
            selection,
            selectionArgs,
            null,
            null,
            sortOrder
    );
    //This line will let CursorLoader know about any data change on "uri" , So that data will be reloaded to CursorLoader
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    return cursor;
}`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接