2013-04-15 10 views
5

Sono di fronte a un problema con Loader.Android - onLoadFinished non chiamato

Ho un'attività, che visualizza l'elenco dei record recuperati dal DB locale. All'avvio dell'attività, i record vengono caricati automaticamente tramite il metodo LoaderManager.initLoader().

Esiste anche la possibilità di aggiornare manualmente l'elenco tramite il pulsante di aggiornamento in ActionBarSherlock. Tuttavia, dopo aver terminato un'altra attività che aggiunge un record al DB, onLoadFinished non viene chiamato.

Sto usando SimpleCursorLoader e qui è frammento di codice dalla attività:

@Override 
public void onStart() { 
    ... 
    getSupportLoaderManager().initLoader(0, null, this); 
} 

@Override 
public void onPause() { 
    ... 
    getSupportLoaderManager().destroyLoader(0); 
} 

public void refreshRecords() { 
    getSupportLoaderManager().restartLoader(0, null, this); 
} 

@Override 
public Loader<Cursor> onCreateLoader(int id, final Bundle args) { 
Loader<Cursor> l = new SimpleCursorLoader(this) { 
    @Override 
    public Cursor loadInBackground() { 
     return recordDAO.getCursor(); 
    } 
}; 
l.forceLoad(); 
return l; 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor c) { 
    // updateUI 
} 

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
} 

Il problema è che dopo aver terminato l'altra attività, onLoaderCreate si chiama, ma onLoaderFinished non viene chiamato.

dopo un po 'di debug, ho trovato che SimpleCursorAdapter.deliverResults() si chiama anche, gemma finisce sul .. if (isReset()) { ..

Mi sto perdendo qualcosa? Come forzare il ricaricamento dei dati?

Grazie in anticipo

risposta

14

ho finalmente trovato la soluzione a questo problema grazie alla discussione sulle

https://groups.google.com/forum/#!topic/android-developers/DbKL6PVyhLI

public static <T> void initLoader(final int loaderId, final Bundle args, final LoaderCallbacks<T> callbacks, 
     final LoaderManager loaderManager) { 
    final Loader<T> loader = loaderManager.getLoader(loaderId); 
    if (loader != null && loader.isReset()) { 
     loaderManager.restartLoader(loaderId, args, callbacks); 
    } else { 
     loaderManager.initLoader(loaderId, args, callbacks); 
    } 
} 
+0

Lavori per me. Grazie. –

+7

Non funziona per me! – Radu

+3

Quasi la soluzione corretta: come menzionato su https://groups.google.com/forum/#!topic/android-developers/DbKL6PVyhLI (e l'ho sperimentato), la condizione di reset è! Loader.isReset(), cioè, 'Dovresti riavviare il caricatore solo se il caricatore NON è resettato.' (scritto da Etienne). Si prega di aggiornare la risposta. – Pascal

1

FWIW, ho avuto un problema simile di tentare di riavviare immediatamente il caricatore una seconda volta, prima che venisse chiamato il primo onLoadFinished, senza che venisse chiamato.

questo ha funzionato per me:

if(loader == null) 
    loader = loaderMngr.initLoader(
     0, null, myLoaderCallbacks 
     ); 
else if(loader.isAbandoned()) 
    return; 
else 
    loaderMngr.restartLoader(
     0, null, myLoaderCallbacks 
     );  
4

soluzione RaB non funzionano per me

mio lavorato Soluzione, è stato sempre distruggere Loader prima del riavvio

Loader<Cursor> loader = mLoaderManager.getLoader(mKeyLoader); 
if (loader != null) 
{ 
    mLoaderManager.destroyLoader(mKeyLoader); 
} 
mLoaderManager.restartLoader(mKeyLoader, args, this); 
+0

Ha funzionato per me, grazie! – szidijani

+0

Grazie. Alla fine ho trovato un motivo per cui forzare il loader chiama sempre metodo onLoadFinished. – MistaGreen

1

Oltre alla risposta di Rab , se utilizzi un numero personalizzato Loader, assicurati che se chiami super se superi scrivere deliverResult():

@Override 
public void deliverResult(D data) { 
    super.deliverResult(data); // <--onLoadFinished() will not be called if you don't call this 
    ... 
}