Error al guardar el estado: objetivo no en el gestor de fragmentos (setTargetFragment)

Tengo un accidente de mono

java.lang.IllegalStateException: Failure saving state: FragmentB has target not in fragment manager: FragmentA at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1561) at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:475) at com.acme.ParentActivity.onSaveInstanceState(Unknown Source) 

Básicamente, FragmentA carga FragmentB y setTargetFragment se llama para establecer el fragmento de destino de FragmentB.

FragmentB entonces simplemente llama getTargetFragment en su método onCreate y se cuelga en el destino para cuando sea necesario.

Ahora no estoy haciendo nada en ninguna de las llamadas onSaveInstanceState con el fragmento de destino en términos de establecerlo nulo, haciendo cualquier saveFragmentInstanceState , putFragment etc llamadas. La pregunta es si debo hacer algo con ella?

Gracias por adelantado,

Peter.

** Edit 1 ** Estoy usando una versión antigua de la biblioteca de soporte y tengo la sensación de que esto puede ser arreglado en la última versión, probará más y proporcionará una actualización adicional si ese es el caso. Sin embargo, sigue interesado en saber si debo hacer algo con el fragmento de destino que no estoy haciendo actualmente.

** Edición 1 ** Corregido con la versión 8 de la biblioteca de soporte (no he probado otros).

En realidad, hay dos cosas que debe hacer para resolver este problema:

1. Asegúrese de utilizar getChildFragmentManager () NOT getFragmentManager () al iniciar FragmentB de FragmentA

Llamar a getChildFragmentManager () devolverá FragmentManager del Fragmento de alojamiento, mientras que getFragmentManager () devolverá FragmentManager de la actividad de alojamiento. Es importante utilizar getChildFragmentManager () porque está anidando un Fragmento dentro de otro Fragmento, por lo que el Fragmento padre debe encargarse de manejar cualquier transacción con el Fragmento anidado. Si utiliza getFragmentManager (), se encontrará con el problema que está experimentando en este momento.

2. NO utilice setTargetFragment () y getTargetFragment (), no funcionarán cuando se utiliza getChildFragmentManager ()

En su lugar, utilice getParentFragment (). Creo que hay algún tipo de error en Android ahora mismo donde incluso si usted llama correctamente

fragmentB.setTargetFragment(fragmentA, 0);

Y luego mostrar FragmentB, después de un cambio de configuración, llamando getTargetFragment () de FragmentB se devolverá en lugar de FragmentA.

He aquí una solución:

Poner esto en el fragmento que causa los problemas:

 @Override public void onSaveInstanceState(final Bundle outState) { setTargetFragment(null, -1); ... 

Y recuerde configurarlo en el fragmento de destino real cuando lo necesite.

Nos topamos con este tema recientemente. Hemos implementado un adaptador personalizado que amplía android.support.v4.app. FragmentStatePagerAdapter . Con android.support.v4.app. FragmentManager , hemos configurado varios fragmentos en el buscapersonas, así como varios otros fragmentos fuera del buscapersonas. Los fragmentos se gestionan en una sola actividad. Hay algunos casos en los que estábamos fijando el objetivo (con setTargetFragment ) de fragmentos de no paginación a fragmentos que pueden o no estar contenidos en el adaptador de paginación. Debido a que FragmentStatePagerAdapter sólo mantiene un cierto número de fragmentos, los fragmentos que se establecieron como objetivos y lo que FragmentStatePagerAdapter consideró que ya no se necesitan, fueron destruidos … y un estado potencialmente inconsistente si los fragmentos que tenían esos objetivos todavía existían. Esto llevó a la excepción que se lanzó cada vez que la aplicación perdió el foco (ya sea cuando la pantalla se apagó o la aplicación entró en el fondo), es decir, cuando onSaveInstanceState se llamó.

Para evitar esta excepción, en onSaveInstanceState , comprobamos para ver qué fragmentos estaban actualmente en el gestor de fragmentos. Si hubo alguna inconsistencia (es decir, faltaba un fragmento "objetivo"), eliminamos el fragmento que tenía ese objetivo establecido. En nuestro caso, sólo teníamos tres fragmentos en los que estábamos fijando un objetivo por lo que sabíamos exactamente qué buscar.

No creo que haya otra manera de manejar este caso, pero si alguien tiene algún comentario útil, sería muy apreciado.

¡Asegúrate de haber agregado ambos fragmentos a la pila posterior!

Acabo de llegar a este problema al agregar un nuevo fragmento 'llamado' para el resultado en la parte superior de un fragmento 'objetivo'. Inicialmente, estaba recibiendo el mismo error, que dejó de ocurrir tan pronto como agregué ambos fragmentos a la pila trasera cuando los usaba.

El problema se produjo en rotaciones de pantalla, por lo que fue fácil de reproducir.

Hubo pocos cambios en el orden de ciclo de vida de onSaveInstance () entre las bibliotecas Pre-HoneyComb y post-Honeycomb. Consulte este artículo para obtener más información:

http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

Acabo de enfrentar este problema y esto es lo que creo que está sucediendo y cómo lo arreglé:

La instancia de FragmentA se está destruyendo y otra está siendo creada cuando hay una rotación de dispositivo, por ejemplo. Cuando esto sucede, su FragmentB mantiene la celebración de una referencia a un FragmentA que ya no existe.

En este caso, debe restablecer el objetivo de FragmentB para que sea la nueva instancia de FragmentA.

Lo hice con el siguiente código en FragmentA:

 @Override public void onAttach(Context context) { super.onAttach(context); FragmentB fragment = (FragmentB) getFragmentManager().findFragmentByTag(FragmentBtag); if (fragment != null) { fragment.setTargetFragment(this, 0); } } 

De esta manera, siempre que el fragmentoA se adjunta al contexto, es decir: se produce una rotación de dispositivo, el objetivo de FragmentB se restablece, si FragmentB se creó de primera mano (si es así, sería en FragmentManager).

Espero que ayude.

Tuve este problema al mostrar un DialogFrament de otro fragmento y usar setTargetFragment en el DialogFragment. El problema se resolvió mediante getChildFragmentManager () al mostrar el DialogFragment.

  1. ActivityA agregó FragmentA
  2. FragmentA agregó DialogFragmentB usando el FragmentManager de ActivityA.
  3. Se llama dialogFragmentB.setTargetFragment (fragmentA)
  4. Se eliminó FragmentA y se añadió nueva instancia de FragmentA
  5. El FragmentManager asociado con ActivityA contenía todavía DialogFragmentB que tenía la primera instancia de FragmentA como fragmento de destino.

Esto provocó la excepción "Error de estado de almacenamiento – objetivo no en el gestor de fragmentos".

  • La aplicación se bloquea después de agregar el fragmento
  • Tratando de agregar un fragmento a mi contenedor de fragmentos FrameLayout
  • Actualizar el fragmento cuando se desactiva el diálogo
  • Fragmento que no llama onPause o onStop cuando se usa replace
  • Espere hasta que se haya agregado fragmento a la interfaz de usuario
  • El método makeText en el tipo Toast no es aplicable para los argumentos
  • Uso de las clases Fragment y AppCompatActivity juntos
  • Android - Cómo cambiar dinámicamente el diseño del fragmento
  • ¿Es posible animar un DialogFragment?
  • Fragmento: Nombre de animación desconocido objectanimator
  • La mejor manera de implementar varios diálogos de alertas en una actividad
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.