tutorial studio implement how fragments example ejemplo dinamicos java android android-fragments fragmentmanager

java - studio - Android FragmentManager BackStackRecord.run lanzando NullPointerException



how to implement fragments in android studio (2)

A veces obtengo la siguiente excepción cuando trabajo con 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)

La excepción se produce cuando se llama a run() de BackStackRecord través de execPendingTransactions() , cuando intenta eliminar un fragmento del administrador.

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

Parece que no puedo averiguar qué está causando esto exactamente. Creo que tiene que ver con el backstack de fragmentos que no se limpian correctamente al eliminar fragmentos.


No uso etiquetas para crear los fragmentos (funcionan como contenedores TabBar).

Entonces, funciona cuando cambio la pestaña, pero si presiono el botón Atrás, recibí el mismo error.

En el método onDestroyView encontré la instancia de fragmento con FragmentManager # findFragmentById, sin embargo FragmentManager # findFragmentByTag devuelve null, claro.

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; } } }


Respondiendo mi propia pregunta:

Esta excepción se lanza (eventualmente) cuando llamas a FragmentTransaction.remove(null); y FragmentTransaction.commit();

EDITAR: Y también, como Twice Circled y shinyuX señalan en el comentario; al llamar a los métodos show(null) o add(null) , attach(null) y detach(null) , y probablemente también hide(null)

Después de llamar a commit() , la transacción se pondrá en cola en FragmentManager. Como resultado, cuando la operación se está procesando después de llamar explícitamente a FragmentManager.executePendingTransactions() , o cuando el hilo de cola de FragmentManager lo llama, arroja una NullPointerException .

En mi caso, mantuve estados de fragmentos en un objeto global. Allí revisé si el fragmento se mostraba o no, y luego eliminé los fragmentos visibles. Pero debido a que comencé una nueva FragmentActivity, estos estados todavía se configuraron como verdaderos mientras no eran visibles. Entonces este es un error de diseño.

Aparte de corregir el error de diseño, la solución era simple: verificar si FragmentManager.findFragmentByTag() devolvía el null antes de eliminar el fragmento.