J'obtiens parfois l'exception suivante lorsque je travaille avec Fragments:
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é via execPendingTransactions()
, lorsqu'il tente de supprimer 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 ça? Je pense que cela a à voir avec le tas de fragments ne sont pas nettoyés correctement lors de la suppression des fragments.
Répondre à ma propre question:
Cette exception est (éventuellement) levée lorsque vous appelez FragmentTransaction.remove(null);
et FragmentTransaction.commit();
EDIT: Et aussi, comme deux fois cerclé et shinyuX soulignent dans le commentaire; en appelant les méthodes show(null)
ou add(null)
, attach(null)
et detach(null)
, et probablement aussi hide(null)
Après avoir appelé commit()
, la transaction sera mise en file d'attente dans FragmentManager. Par conséquent, lorsque l'opération est en cours de traitement après l'appel explicitement de FragmentManager.executePendingTransactions()
ou lorsque le thread de la file d'attente de FragmentManager l'appelle, elle renvoie une 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 j'ai retiré les fragments visibles. Mais comme j'ai commencé une nouvelle FragmentActivity, ces états étaient toujours définis sur true alors qu'ils n'étaient pas visibles. C'est donc une erreur de conception.
Outre la correction de l'erreur de conception, la solution était simple: vérifiez si FragmentManager.findFragmentByTag()
a retourné null
avant de supprimer le fragment.
La seule raison pour laquelle il arrive, c'est l'invocation
getSupportFragmentManager().beginTransaction().remove(fragment)
alors que fragment
est null