2012-11-15 3 views
65

je reçois parfois l'exception suivante lorsque vous travaillez avec des fragments:Android FragmentManager BackStackRecord.run lancer NullPointerException

FATAL EXCEPTION: main 
java.lang.NullPointerException 
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:591) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420) 
    at android.os.Handler.handleCallback(Handler.java:615) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4745) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 

L'exception se produit lorsque run() de BackStackRecord est appelé par execPendingTransactions(), quand il tente de retirer un fragment du gestionnaire .

case OP_REMOVE: { 
    Fragment f = op.fragment; 
    f.mNextAnim = op.exitAnim; <---- 
    mManager.removeFragment(f, mTransition, mTransitionStyle); 
} 
break; 

Je n'arrive pas à comprendre ce qui cause exactement cela? Je pense que cela a à voir avec le backstack de fragments qui ne sont pas nettoyés juste en enlevant des fragments.

Répondre

158

répondre à ma propre question:

Cette exception est (éventuellement) lancée lorsque vous appelez FragmentTransaction.remove(null); et FragmentTransaction.commit();

EDIT: Et aussi, comme deux fois et CircleD shinyuX soulignez dans le commentaire; lorsque vous appelez les show(null) ou add(null), attach(null) et detach(null) méthodes, et probablement aussi hide(null)

Après avoir appelé commit(), la transaction sera mis en attente dans le FragmentManager. Par conséquent, lorsque l'opération est en cours de traitement après avoir appelé explicitement FragmentManager.executePendingTransactions() ou lorsque l'unité d'exécution de la file d'attente FragmentManager l'appelle, elle lance NullPointerException.

Dans mon cas, je maintenais des états de fragment dans un objet global. Là, j'ai vérifié si le fragment était visible ou non, puis enlevé les fragments visibles. Mais parce que j'ai commencé une nouvelle FragmentActivity, ces états étaient toujours définis sur true alors qu'ils n'étaient pas visibles. Donc, ceci est une erreur de conception.

Outre la correction de l'erreur de conception, la solution était simple: vérifier si FragmentManager.findFragmentByTag() renvoyait null avant d'enlever le fragment.

+14

Bonne réponse - Ceci m'a aidé à résoudre mon propre problème. Une chose à noter, vous obtiendrez la même erreur lorsque vous appelez FragmentTransaction.show (null), .hide (null), etc. pas seulement .remove (null). Espérons que cela aidera les autres à retrouver leur problème. –

+0

Merci @ Nickick ...... – hemu

+1

m'a beaucoup aidé! Notez que ça échouera avec n'importe quelle action envoyée avec un fragment nul (dans mon cas 'attach'' detach') – shinyuX

-2

Je n'utilise pas de balise pour créer les fragments (ils fonctionnent comme des conteneurs TabBar). Donc, ça marche quand on change d'onglet, mais si j'appuie sur le bouton précédent, j'ai la même erreur.

À la méthode onDestroyView, j'ai trouvé une instance de fragment avec FragmentManager # findFragmentById, cependant FragmentManager # findFragmentByTag renvoie null, bien sûr.

class MyFragment extends ListFragment { 

@Override 
public void onDestroyView() { 
    super.onDestroyView(); 

    if (this.mapFragment != null 
      && getFragmentManager().findFragmentById(
        this.mapFragment.getId()) != null) { 

     getFragmentManager().beginTransaction().remove(this.mapFragment) 
       .commit(); 
     this.mapFragment = null; 
    } 

} 
} 
+2

Pourquoi est-il nécessaire de définir mapFragment sur null? –

+1

Une question qui mérite d'être posée: - 'Pourquoi est-il nécessaire de définir mapFragment sur null?' – nmxprime

Questions connexes