6

コンテンツ プロバイダー、コンテンツ リゾルバー、およびカーソル ローダーがあります。ローダーは、リストビューを間接的に設定するために使用されます (つまり、カーソルの結果を使用して他のデータを収集する必要があるため、単純なカーソル アダプターではなく、配列アダプターです)。

onLoadFinished(Loader<Cursor>, Cursor)基になるデータを変更すると、コールバックが呼び出されないため、リストビューは再入力されません。

これを書いている間に示唆されたように、この問題には多くの質問があります。例: データ変更後に CursorLoader が更新されない

そして、すべての質問は次の 2 つのことを指摘しています。

  • コンテンツ プロバイダーの 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();

ローダー リセットは、テーブルをクリアします。

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);
}
4

3 に答える 3

2

onLoadFinished と onLoaderReset で swapCursor または changeCursor を呼び出していないようです。アダプターが新しいカーソルにロードされたデータにアクセスするには、これを行う必要があります。

onLoadFinished で、次のように呼び出します。

mAdapter.swapCursor(cursor)

onLoaderReset で、これを呼び出して古いカーソルへの参照を削除します。

mAdapter.swapCursor(null)

mAdapter は listView のアダプターです。

詳細: http://developer.android.com/guide/components/loaders.html#onLoadFinished

于 2013-06-18T20:55:57.323 に答える
1

これは、この特定の問題に対する直接的な回答ではありませんが、同様の状況にある他の人に役立つ可能性があります。私の場合、プロジェクションとクエリで完全な tablename.columnname を使用したにもかかわらず、結合がありました。とにかく、間違った ID 値を使用してしまいました。そのため、必ず ContentProvider または SQL 構文を確認してください。

于 2013-12-23T17:42:27.207 に答える