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