2011-09-19 14 views
8

Jeśli używasz niestandardowego AsyncTaskLoader do pobierania danych z usługi internetowej, jeśli naciśniesz przycisk HOME w połowie procesu ładowania, a następnie ponownie wejdziesz do aplikacji, onLoadFinished () metoda nie jest wywoływana. Mój fragment wywołuje setRetainInstance(true) w onActivityCreated() i również wywołuje getLoaderManager.initLoader(0, null, this) w tej samej metodzie (co jest zalecane).onLoadFinished nie jest wywoływane po powrocie z przycisku HOME naciśnij

Podczas testowania widzę, że po powrocie do fragmentu onActivityCreated() nie jest wywoływany, więc może być powodem, dla którego onLoadFinished() nie jest wywoływany. Ale gdzie jeszcze umieścić metodę initLoader()? W kilku miejscach przeczytałem, że nie powinno się go wywoływać w onResume().

Jakieś pomysły? Mam wiele programów ładujących na różnych ekranach w mojej aplikacji i muszę rozwiązać ten problem w elegancki sposób.

+0

Gdzie można przeczytać, że 'initloader' nie powinien być nazywany w 'onResume()', ponieważ jest to dokładnie to, co jest wymagane, aby obejść błąd struktury https://code.google.com/p/android/issues/detail?id=63179 – faizal

+0

@faizal Naprawdę nie pamiętam. Od dawna odchodzę od używania ładowarek. Wielu doświadczonych programistów zaleca odradzanie używania ładowarek do pobierania danych sieciowych. –

Odpowiedz

22

Po obejrzeniu Issue 14944 (http://code.google.com/p/android/issues/detail?id=14944), I rozwiązać problem poprzez nadpisanie onStartLoading() w moim zwyczaju AsyncTaskLoader i nazywają forceLoad().

Jeszcze lepszym rozwiązaniem jest stworzenie własnego rodzica AsyncTaskLoader który wygląda tak (wzięte z sugestią przez alexvem z linku powyżej):

public abstract class AsyncLoader<D> extends AsyncTaskLoader<D> { 

    private D data; 

    public AsyncLoader(Context context) { 
     super(context); 
    } 

    @Override 
    public void deliverResult(D data) { 
     if (isReset()) { 
      // An async query came in while the loader is stopped 
      return; 
     } 

     this.data = data; 

     super.deliverResult(data); 
    } 


    @Override 
    protected void onStartLoading() { 
     if (data != null) { 
      deliverResult(data); 
     } 

     if (takeContentChanged() || data == null) { 
      forceLoad(); 
     } 
    } 

    @Override 
    protected void onStopLoading() { 
     // Attempt to cancel the current load task if possible. 
     cancelLoad(); 
    } 

    @Override 
    protected void onReset() { 
     super.onReset(); 

     // Ensure the loader is stopped 
     onStopLoading(); 

     data = null; 
    } 
} 
+0

Rozwiązany dla mnie przez przesłonięcie opcjiStartLoading() i wywołanie w nim forceLoad(). – sandy

Powiązane problemy