当基础数据更改时,Cursorloader不刷新

问题描述 投票:6回答:3

我有一个内容提供者,一个内容解析器和一个游标加载器。加载程序用于间接填充列表视图(即,不是简单的游标适配器,而是数组适配器,因为我需要使用游标的结果来收集其他数据)。

当我更改基础数据时,由于未调用onLoadFinished(Loader<Cursor>, Cursor)回调,因此列表视图不会重新填充。

正如我在撰写本文时所建议的那样,对此问题有很多疑问。例如CursorLoader not updating after data change

所有问题都指出了两件事:

  • 在您的内容提供者query()方法中,您需要告诉光标有关通知的提示'>
  • c.setNotificationUri(getContext().getContentResolver(), uri);

  • 在内容提供者的插入/更新/删除方法中,您需要在URI上进行通知:
  • getContext().getContentResolver().notifyChange(uri, null);

我正在做这些事情。

我也不关闭我返回的任何游标。

[请注意,我的内容提供商位于单独的应用程序中(可以将其视为内容提供商应用程序-没有启动程序的主要活动)。一个com.example.provider APK,并且com.example.app正在通过content://com.example.provider/table URI等进行调用(在内容解析器中)。内容解析器(dbhelper)位于库项目中(com.example.appdb)链接到活动。(这样,多个项目可以通过链接使用dbhelper,并且所有内容提供程序都通过单个APK安装)

我已经在加载程序管理器中打开了调试功能,并且可以看到在数据更改后(例如,加载程序已重新启动并且先前被标记为非活动状态),在什么地方我进行了刷新,但是什么也没说是自动发生的,而是回应我的部队刷新。

关于为什么不刷新加载程序的任何想法?

-编辑-

装载程序创建:

Log.d(TAG, "onCreateLoader ID: " + loaderID);
// typically a switch on the loader ID, and then 
return dbHelper.getfoo()

其中getfoo()通过以下方式返回游标加载器:

return new CursorLoader(context, FOO_URI, foo_Fields, foo_query, foo_argArray, foo_sort );

Loader Finish会获取光标并填充一个表(并进行一些处理)-在那里没有什么幻想。

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    Log.d(TAG, "onLoadFinished id: " + loader.getId());
    // switch on loader ID .. 
    FillTable(cursor, (FooAdapter) foo_info.listview.getAdapter();

Loader Reset清除表。

public void onLoaderReset(Loader<Cursor> loader) {
    Log.d(TAG, "onLoaderReset id: " + loader.getId());
    // normally a switch on loader ID
    ((FooAdapter)foo_info.listview.getAdapter()).clear();

内容提供商这样做:

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    Cursor cursor;
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        SQLiteDatabase db = dbHelper.getReadableDatabase();

        switch (sUriMatcher.match(uri)) {
        case FOO:
            qb.setTables(FOO);
            qb.setProjectionMap(FooProjectionMap);
            break; 
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);

        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
}

然后插入/更新是类似的:

public Uri insert(Uri uri, ContentValues initialValues) {
    ContentValues values;
    if (initialValues != null) {
        values = new ContentValues(initialValues);
    } else {
        values = new ContentValues();
    }

    String tableName;
    Uri contentUri;

    switch (sUriMatcher.match(uri)) {
    case FOO:
        tableName = FOOTABLE;
        contentUri = FOO_URI;
        break;

    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    SQLiteDatabase db = dbHelper.getWritableDatabase();
    long rowId = db.insert(tableName, null, values);
    if (rowId > 0) {
        Uri objUri = ContentUris.withAppendedId(contentUri, rowId);
        getContext().getContentResolver().notifyChange(objUri, null);
        return objUri;
    }

    throw new SQLException("Failed to insert row into " + uri);
}

我有一个内容提供者,一个内容解析器和一个游标加载器。加载程序用于间接填充列表视图(即,不是简单的游标适配器,而是数组适配器,因为我需要使用...

android android-cursorloader
3个回答
2
投票

我发现您没有在onLoadFinished和onLoaderReset中调用swapCursor或changeCursor。您需要执行此操作,适配器才能访问加载到新游标中的数据。


2
投票

所以,对于那些查找并有此问题的人:


1
投票

这不是对该特定问题的直接答案,但可能会在类似情况下帮助其他人。就我而言,我有一个联接,即使我在投影和查询中使用了完整的tablename.columnname。最终还是使用了错误的ID值。因此,请务必检查您的ContentProvider或SQL语法。

© www.soinside.com 2019 - 2024. All rights reserved.