Ich habe einen Inhaltsanbieter, einen Content-Resolver und einen Cursor-Loader. Der Loader wird verwendet, um eine Listview indirekt zu füllen (dh kein einfacher Cursor-Adapter, sondern ein Array-Adapter, da ich die Ergebnisse des Cursors verwenden muss, um andere Daten zu sammeln).Cursorloader nicht aktualisiert, wenn sich die zugrunde liegenden Daten ändern
Wenn ich die zugrunde liegenden Daten ändern, wird die Listview nicht ausgefüllt, da der Rückruf onLoadFinished(Loader<Cursor>, Cursor)
nicht aufgerufen wird.
Wie vorgeschlagen, während ich dies schreibe, gibt es eine Menge Fragen zu diesem Thema. zB CursorLoader not updating after data change
Und alle Fragen weisen darauf hin, zwei Dinge:
- In Ihrem Content-Provider-Abfrage() -Methode, müssen Sie a'la den Cursor über Benachrichtigungen sagen
c.setNotificationUri(getContext().getContentResolver(), uri);
- In Ihrem Content-Provider einfügen/update/delete-Methode müssen Sie n otify auf der URI:
getContext().getContentResolver().notifyChange(uri, null);
ich diese Dinge zu tun.
Ich schließe auch keinen der Cursor, die ich zurückbekomme.
Beachten Sie, dass mein Inhaltsanbieter in einer separaten App lebt (denken Sie daran, dass es sich um eine App für den Inhaltsanbieter handelt - keine Hauptaktivität des Startprogramms). Ein com.example.provider APK, und die com.example.app ruft (im content resolver) über den content: //com.example.provider/table URI etc. auf. Der content resolver (dbhelper) lebt in einem Bibliotheksprojekt (com.example.appdb), mit dem die Aktivität verknüpft wird. (Auf diese Weise können mehrere Projekte den dbhelper via Linking verwenden, und alle Inhaltsanbieter werden über ein einzelnes APK installiert)
Ich habe das Debugging im Loader Manager aktiviert, und kann sehen, wo ich eine Aktualisierung erzwinge, nachdem sich die Daten geändert haben (dh der Loader wird neu gestartet und der vorherige wird als inaktiv markiert), aber nichts, was etwas sagt, passiert automatisch - eher als Reaktion auf meine Force-Aktualisierung.
Irgendwelche Ideen, warum mein Ladeprogramm nicht aktualisiert wird?
- EDIT -
Der Lader erstellen:
Log.d(TAG, "onCreateLoader ID: " + loaderID);
// typically a switch on the loader ID, and then
return dbHelper.getfoo()
Wo getFoo() über einen Cursor loader zurückgibt:
return new CursorLoader(context, FOO_URI, foo_Fields, foo_query, foo_argArray, foo_sort);
Loader-Finish führt den Cursor und füllt eine Tabelle (und tut etwas Verarbeitung) - nichts Besonderes dort.
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 löscht die Tabelle.
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();
Der Inhaltsanbieter hat:
public Cursor query (Uri uri, String [] Projektion, String Auswahl, String [] selectionArgs, String sortOrder) { Cursor Cursor; SQLiteQueryBuilder qb = neuer 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;
}
Dann Update einfügen/ähnelt:
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);
}
Das Posten eines Teils Ihres Codes im Zusammenhang mit dem Cursor Loader könnte helfen. Hauptsächlich Ihre Methoden onCreateLoader, onLoaderReset und onLoadFinished. Ich nehme an, dass Ihr ContentProvider den NotifyChange-Aufruf beim Aktualisieren erreicht. – AfzalivE
Sorry, Stürme/Stromausfall usw. hielten mich für einige Zeit fern. –