53 votes

Android: LoaderCallbacks.OnLoadFinished appelé deux fois

J'ai remarqué d'étrange situation à l'aide d'Android Chargeurs et des Fragments. Quand j'invoque LoaderManager.initLoader() après le changement d'orientation onLoadFinished n'est pas appelé (bien que la documentation suggère que je devrais être prêt pour cela), mais il est appelé à deux reprises par la suite. Voici le lien pour poster dans google groupes qui décrivent la même situation https://groups.google.com/forum/?fromgroups#!topic/android-développeurs/aA2vHYxSskU . J'ai écrit à l'application de l'échantillon dans lequel je ne init Chargeur simple Fragment.onActivityCreated() pour vérifier si cela arrive et il ne. Quelqu'un l'a remarqué?

38voto

Andrew Points 1532

Vous pouvez mettre la méthode initLoader () dans le rappel onResume () de votre fragment; alors onLoadFinished () du chargeur ne sera plus appelé deux fois.

     @Override
public void onResume()
{
    super.onResume();
    getLoaderManager().initLoader(0, null, this);
}
 

28voto

Matt Points 2133

Ce problème s'est manifesté pour moi avec un CursorLoader retour d'un Curseur qui était déjà fermée:

android.database.StaleDataException: Attempted to access a cursor after it has been closed.

J'avais suppose que c'est un bug ou un oubli. Tout en se déplaçant initLoader() dans onResume de travail, ce que j'ai pu faire, c'était de retirer le Chargeur quand je suis fait avec ça:

Pour démarrer le chargeur (dans mon onCreate):

  getLoaderManager().initLoader(MUSIC_LOADER_ID, null, this);

Puis après je suis fait avec ça (en gros à la fin de onLoadFinished)

  getLoaderManager().destroyLoader(MUSIC_LOADER_ID);

Cela semble se comporter comme prévu, pas d'appels supplémentaires.

6voto

jperera Points 76

Au initLoader documentation http://developer.android.com/reference/android/app/LoaderManager.html#initLoader(int,%20android.os.Bundle,%20android.app.LoaderManager.LoaderCallbacks), vous pouvez lire:

"Si au moment de l'appel de l'appelant est dans son état démarré, et la demande d'chargeur existe déjà et a généré ses données, puis de rappel onLoadFinished(Chargeur, D)"

Je vous suggère de mettre en place quelque chose comme onStartLoading fonction d'exemple http://developer.android.com/reference/android/content/AsyncTaskLoader.html

Pour le test rapide, vous pouvez essayer:

@Override protected void onStartLoading() {
    forceLoad();
}

Ce lancement loadInBackground la fonction, puis onLoadFinished dans le Fragment.

De toute façon, si vous fixez un peu de code, je vais essayer de vous donner plus d'aide.

3voto

vovkab Points 563

Le problème est qu'il a appelé deux fois: 1. depuis Fragment.onStart 2. depuis FragmentActivity.onStart

La seule différence est que dans Fragment.onStart, il vérifie si mLoaderManager! = Null. Cela signifie que si vous appelez getLoadManager avant onStart, comme dans onActivityCreated, il obtiendra / créera le gestionnaire de charge et sera appelé. Pour éviter cela, vous devez l'appeler plus tard, comme dans onResume.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X