Ho un provider di contenuti, un risolutore di contenuto e un caricatore di cursori. Il caricatore viene utilizzato per compilare indirettamente un listview (cioè non un semplice adattatore per il cursore, piuttosto un adattatore di array, poiché ho bisogno di usare i risultati del cursore per raccogliere altri dati).Il Cursorloader non si aggiorna quando i dati sottostanti cambiano
Quando cambio i dati sottostanti, la list list non viene popolata non viene richiamata la chiamata onLoadFinished(Loader<Cursor>, Cursor)
.
Come suggerito mentre sto scrivendo questo, ci sono molte domande su questo problema. esempio CursorLoader not updating after data change
E tutte le domande sottolineano due cose:
- Nel suo sito web interrogazione fornitore del metodo(), è necessario indicare il cursore sulle notifiche a'la
c.setNotificationUri(getContext().getContentResolver(), uri);
- Nel metodo di inserimento/aggiornamento/eliminazione del provider di contenuti, è necessario otify sulla URI:
getContext().getContentResolver().notifyChange(uri, null);
sto facendo quelle cose.
Inoltre NON sto chiudendo nessuno dei cursori che torno.
Nota, il mio fornitore di contenuti vive in un'app separata (pensatela come app di content provider - nessuna attività principale di avvio). Un APK com.example.provider e com.example.app sta chiamando (nel resolver del contenuto) tramite il contenuto: //com.example.provider/table URI ecc. Il content resolver (dbhelper) vive in un progetto di libreria (com.example.appdb) in cui l'attività si collega. (In questo modo, più progetti possono utilizzare dbhelper tramite collegamento e tutti i provider di contenuti sono installati tramite APK singolo)
Ho attivato il debug nel gestore di caricamento, e posso vedere dove forzare un aggiornamento dopo che i dati sono cambiati (cioè il riavvio del caricatore e la precedente marcatura inattiva), ma nulla che dice che qualcosa sta accadendo automaticamente - piuttosto, in risposta al mio aggiornamento forzato.
Qualche motivo per cui il mio caricatore non viene aggiornato?
- EDIT -
Il caricatore creare:
Log.d(TAG, "onCreateLoader ID: " + loaderID);
// typically a switch on the loader ID, and then
return dbHelper.getfoo()
Dove getFoo() restituisce un caricatore cursore attraverso:
return new CursorLoader(context, FOO_URI, foo_Fields, foo_query, foo_argArray, foo_sort);
Loader Fine prende il cursore e popola un tavolo (e fa un po 'di elaborazione) - niente di speciale lì.
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();
Il reset del caricatore cancella la tabella.
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();
Il fornitore di contenuti fa:
query del cursore pubblica (Uri uri, String proiezione [], selezione String, selectionArgs String [], String sortorder) { cursore Cursore; 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;
}
Poi inserimento/aggiornamento è simile:
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);
}
L'invio di parte del codice correlato al Cursor Loader può essere d'aiuto. Principalmente i tuoi metodi onCreateLoader, onLoaderReset e onLoadFinished. Suppongo che ContentProvider raggiunga la chiamata notifyChange quando si aggiorna. – AfzalivE
Scusa, tempeste/interruzioni di corrente, ecc. Mi hanno tenuto lontano per un po 'di tempo. –