¿Cómo puedo romper las cosas con Fragmentos con setRetainInstance (true) y agregarlos a backstack?

Los documentos en setRetainInstance dicen:

Esto sólo puede usarse con fragmentos que no estén en la pila trasera.

Así que empecé a jugar con él.

Tengo una Actividad con el primer fragmento A

FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content, new PackageFragment()); ft.commit 

Entonces de este frag I ejecutar un método de la actividad padre que añade frag B a backstack

 FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content, new OrderFragment()); ft.addToBackStack(null); ft.commit(); 

Entonces creo msg de registro de onCreate, onDestroy, onSaveInstanceState, onActivityCreated … etc

Intento dos versiones de este proceso. Rotar el dispositivo en cada fragmento.

  1. defecto

Todo es como se esperaba. OnCreate, onDestroy en fragmentos de fuego

  1. SetRetainInstance (true)

Todo es como se esperaba ?. OnCreate, onDestroy en los fragmentos dont fire

Y todo parece trabajar mientras que los fragmentos están en el backstack. ¿Tan porqué los docs dicen que no debería usarlo? ¿Cuáles son los escenarios en los que podría tener problemas?

Gracias

Respuesta actualizada:

¿Cuáles son los escenarios en los que podría tener problemas?

Al agregar un Fragment a la pila trasera y pasar un Bundle en el Fragment de onSaveInstanceState() a onCreateView() en el cambio de configuración. Llamar setRetainInstance(true) establecerá el Bundle en null en el cambio de configuración.

(No estoy seguro de que un desarrollador realmente intente esto ya que usar setRetainInstance(true) hace onSaveInstanceState() tipo de redundante, pero no vi el comportamiento documentado en los documentos de API así que escribí esta respuesta).

Si se addToBackStack() vez addToBackStack() y setRetainInstance(true) , setRetainInstance() modifica parcialmente las llamadas al método del ciclo de vida Fragment y los valores de los parámetros en los cambios de configuración, en comparación con llamar a addToBackStack() .

En concreto, en la prueba que se muestra a continuación, buscar diferencias entre llamar a addToBackStack() y llamar a setRetainInstance(true) también, y ver qué sucede en el cambio de configuración:

Llamar addToBackStack() pero no setRetainInstance(true) ;

  • onCreate() y onDestroy() son llamados.
  • Un paquete que se pasa desde onSaveInstanceState() se recibe como un parámetro en onCreateView() .

Llamar a ambos addToBackStack() y setRetainInstance(true) :

  • onCreate() y onDestroy() no se llaman. Esto se encuentra en los documentos de la API.
  • Un paquete que se pasa desde onSaveInstanceState() no se recibe en onCreateView() . El Bundle transferido es nulo.

Una prueba con las llamadas de método registradas y parámetros probados para null:

En la Activity :

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyFragment fragment; if (savedInstanceState != null) { fragment = (MyFragment) getFragmentManager().findFragmentByTag("my_fragment_tag"); } else { fragment = new MyFragment(); FragmentTransaction t = getFragmentManager().beginTransaction(); t.addToBackStack(null);//toggle this t.add(android.R.id.content, fragment, "my_fragment_tag").commit(); } } 

En el Fragment :

 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setRetainInstance(true);//toggle this } 

y

 @Override public void onSaveInstanceState(Bundle outState) { outState.putString("test", "value"); super.onSaveInstanceState(outState); } 

Prueba 1: addToBackStack() vida del fragmento cuando se llama addToBackStack() y setRetainInstance(true) no se llama

  • OnAttach ()
  • OnCreate ()
  • OnCreateView ()
  • OnActivityCreated ()
  • OnStart ()
  • En resumen()

[Dispositivo girado de retrato a paisaje]

  • OnPause ()
  • OnSaveInstanceState ()
  • OnStop ()
  • OnDestroyView ()
  • OnDestroy ()
  • OnDetach ()
  • OnAttach ()
  • OnCreate ()
  • OnCreateView () con el paquete param! = Null
  • OnStart ()
  • En resumen()

Prueba 2 y 3: Llamadas de ciclo de vida de fragmento con setRetainInstance(true) llamado, addToBackStack() llamado / no llamado (mismo resultado):

  • OnAttach ()
  • OnCreateView ()
  • OnActivityCreated ()
  • OnStart ()
  • En resumen()

[Dispositivo girado de retrato a paisaje]

  • OnPause ()
  • OnSaveInstanceState ()
  • OnStop ()
  • OnDestroyView ()
  • OnDetach ()
  • OnAttach ()
  • OnCreateView () con el paquete param == null
  • OnStart ()
  • En resumen()
  • Problema de orientación de la cámara OpenCV
  • ¿Por qué onLayout y onSizeChanged se llaman dos veces en un cambio de orientación?
  • El video se reproduce en parte de la pantalla después de desbloquear la pantalla
  • Cómo quitar las pestañas de ActionBar en la orientación horizontal sólo para las tabletas
  • El emulador de Android no gira al paisaje
  • Obtener la orientación del dispositivo de Android incluso cuando AutoRotation está desactivado
  • SCREEN_ORIENTATION_LANDSCAPE al revés - ¿Por qué?
  • Cómo funciona la restauración automática de fragmentos
  • ¿Cómo evitar que el diseño se restablezca cuando cambia la orientación de la pantalla?
  • Establecer la orientación horizontal en android en ambos lados
  • Forzar cierre en modo horizontal, pero no en vertical
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.