2013-04-15 23 views
5

Mam do czynienia z problemem z Loader.Android - onLoadFinished nie nazywa się

Mam działanie, które wyświetla listę rekordów pobranych z lokalnego DB. Po rozpoczęciu działania rekordy są ładowane automatycznie za pomocą metody LoaderManager.initLoader().

Istnieje również możliwość ręcznego odświeżenia listy za pomocą przycisku odświeżania w ActionBarSherlock. Jednak po zakończeniu innej czynności, która dodaje rekord do DB, onLoadFinished nie jest wywoływany.

Używam SimpleCursorLoader A oto fragment kodu z działalności:

@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) { 
} 

Kwestia jest taka, że ​​po zakończeniu innej działalności, onLoaderCreate nazywa, ale onLoaderFinished nie nazywa.

po pewnym debugowania Znalazłem że SimpleCursorAdapter.deliverResults() nazywany jest również, bud kończy się na .. if (isReset()) { ..

Am I czegoś brakuje? Jak wymusić przeładowanie danych?

góry dziękuję

Odpowiedz

14

I w końcu znaleźć rozwiązanie tego problemu dzięki dyskusji na

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

pracuje dla mnie. Dziękuję Ci. –

+7

Nie działa dla mnie! – Radu

+3

Prawie poprawne rozwiązanie: jak wspomniano na https://groups.google.com/forum/#!topic/android-developers/DbKL6PVyhLI (i eksperymentowałem z nim), warunkiem resetowania jest! Loader.isReset(), czyli "Powinieneś uruchomić ponownie program ładujący, jeśli program ładujący NIE JEST zresetowany." (napisany przez Etienne). Zaktualizuj swoją odpowiedź. – Pascal

1

FWIW, miałem podobny problem z przystąpieniem do natychmiastowego ponownego uruchomienia program ładujący po raz drugi, zanim wywołano pierwszą funkcję onLoadFinished, co spowodowało, że żaden z nich nie był wywoływany.

ten pracował dla mnie:

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

rozwiązanie rab nie działa dla mnie

My pracował Rozwiązanie, zawsze zniszczyć Loader przed ponownym uruchomieniem

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

Pracowałem dla mnie, dzięki! – szidijani

+0

Dzięki. W końcu znalazłem, dlaczego wymuszanie ładowania zawsze wywołuje metodęLoadFinished. – MistaGreen

1

oprócz odpowiedzi Rab , jeśli używasz niestandardowego Loader, upewnij się, że jeśli zadzwonisz pod numer super, jeśli Napisać deliverResult():

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