Actividad y Fragmento Ciclos de Vida y Cambios de Orientación

He estado teniendo ediciones muy impares con los Fragments y los cambios de la orientación que han estado haciendo la fuerza se cierra y no seguir un patrón lógico.

Creé una simple aplicación de depuración de ciclo de vida de Activity y Fragment que simplemente implementa cada paso del ciclo de vida de la actividad y del ciclo de vida del fragmento al informar de la llamada al logcat.

Aquí están las clases TestActivity y TestFragment :

TestActivity

 public class TestActivity extends Activity { Context ct = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("ACT", "onCreate called"); ct = getApplicationContext(); FrameLayout fl = new FrameLayout(ct); fl.setId(1000); TestFragment tf = new TestFragment(); getFragmentManager().beginTransaction().add(fl.getId(), tf, "").commit(); setContentView(fl); } @Override protected void onStart() { Log.e("ACT", "onStart called"); super.onStart(); } @Override protected void onResume() { Log.e("ACT", "onResume called"); super.onResume(); } @Override protected void onPause() { Log.e("ACT", "onPause called"); super.onPause(); } @Override protected void onStop() { Log.e("ACT", "onStop called"); super.onStop(); } @Override protected void onDestroy() { Log.e("ACT", "onDestroy called"); super.onDestroy(); } @Override protected void onRestart() { Log.e("ACT", "onRestart called"); super.onRestart(); } } 

TestFragment

 public class TestFragment extends Fragment { Context ctFrag = null; @Override public void onAttach(Activity activity) { Log.e("FRAG", "onAttach called"); super.onAttach(activity); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("FRAG", "onCreate called"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.e("FRAG", "onCreateView called"); ctFrag = ((TestActivity) getActivity()).ct; TextView tv = new TextView(ctFrag); tv.setText("My test TextView"); return tv; } @Override public void onActivityCreated(Bundle savedInstanceState) { Log.e("FRAG", "onActivityCreated called"); super.onActivityCreated(savedInstanceState); } @Override public void onStart() { Log.e("FRAG", "onStart called"); super.onStart(); } @Override public void onResume() { Log.e("FRAG", "onResume called"); super.onResume(); } @Override public void onPause() { Log.e("FRAG", "onPause called"); super.onPause(); } @Override public void onStop() { Log.e("FRAG", "onStop called"); super.onStop(); } @Override public void onDestroyView() { Log.e("FRAG", "onDestroyView called"); super.onDestroyView(); } @Override public void onDestroy() { Log.e("FRAG", "onDestroy called"); super.onDestroy(); } @Override public void onDetach() { Log.e("FRAG", "onDetach called"); super.onDetach(); } } 

Al iniciar, la salida de Logcat sigue el orden esperado ( Activity inicio, cuando el Fragment está conectado, sus llamadas al ciclo de vida se producen, etc.):

 01-29 10:12:50.270: E/ACT(3321): onCreate called 01-29 10:12:50.760: E/FRAG(3321): onAttach called 01-29 10:12:50.760: E/FRAG(3321): onCreate called 01-29 10:12:50.760: E/FRAG(3321): onCreateView called 01-29 10:12:50.770: E/FRAG(3321): onActivityCreated called 01-29 10:12:50.770: E/ACT(3321): onStart called 01-29 10:12:50.770: E/FRAG(3321): onStart called 01-29 10:12:50.770: E/ACT(3321): onResume called 01-29 10:12:50.770: E/FRAG(3321): onResume called 

Pero la cuestión es, cuando ocurre un cambio de orientación, la documentación de Android dice que:

Cuando se produce este cambio, Android reinicia la actividad en ejecución (onDestroy () se llama, seguido por onCreate ())

Lo que sugeriría que debería apagar la Activity y su contenido como sugiere el ciclo de vida (y lo hace) PERO luego pasar por el mismo proceso ordenado recreando la Activity en la nueva orientación. Esto no sucede y parece que el Fragment se intenta recrear y luego se crea un nuevo en la actividad de recreación.

 01-29 10:17:52.249: E/FRAG(3321): onPause called 01-29 10:17:52.259: E/ACT(3321): onPause called 01-29 10:17:52.269: E/FRAG(3321): onStop called 01-29 10:17:52.269: E/ACT(3321): onStop called 01-29 10:17:52.279: E/FRAG(3321): onDestroyView called 01-29 10:17:52.299: E/FRAG(3321): onDestroy called 01-29 10:17:52.299: E/FRAG(3321): onDetach called 01-29 10:17:52.299: E/ACT(3321): onDestroy called 01-29 10:17:52.650: E/FRAG(3321): onAttach called 01-29 10:17:52.650: E/FRAG(3321): onCreate called 01-29 10:17:52.650: E/ACT(3321): onCreate called 01-29 10:17:53.020: E/FRAG(3321): onCreateView called 01-29 10:17:53.020: E/FRAG(3321): onActivityCreated called 01-29 10:17:53.030: E/FRAG(3321): onAttach called 01-29 10:17:53.030: E/FRAG(3321): onCreate called 01-29 10:17:53.030: E/FRAG(3321): onCreateView called 01-29 10:17:53.030: E/FRAG(3321): onActivityCreated called 01-29 10:17:53.060: E/ACT(3321): onStart called 01-29 10:17:53.060: E/FRAG(3321): onStart called 01-29 10:17:53.060: E/FRAG(3321): onStart called 01-29 10:17:53.060: E/ACT(3321): onResume called 01-29 10:17:53.060: E/FRAG(3321): onResume called 01-29 10:17:53.060: E/FRAG(3321): onResume called 

Obviamente, hay un montón de soluciones para resolver esto, pero mi pregunta es ¿por qué sucede esto? ¿Por qué se mantiene y se recrea una referencia de Fragment cuando se supone que es parte de esa Activity que supuestamente está completamente destruida y recreada? Puedo justificar que por Fragment s intencionalmente ser separado de las actividades. Pero lo que estaba causando los problemas, ¿ por qué es el Fragment original unido y recreado antes de la Activity ? Simplemente no parece seguir el ciclo de vida lógico que hace el resto del proceso Android.

Esto sucede porque la actividad llama onSaveInstanceState(Bundle) antes de ser destruida. De forma predeterminada, la actividad está guardando los estados de sus fragmentos en este método.

Más tarde, cuando se vuelve a crear la actividad, los fragmentos antiguos se vuelven a crear en el onCreate(Bundle savedInstanceState) .

Es posible que desee comprobar el código fuente aquí y aquí para comprender mejor este comportamiento.

Es porque usted está agregando el fragmento una y otra vez en la actividad se recrea. Puede utilizar el siguiente código en el método onCreate de la actividad para evitar la recreación del fragmento:

 if(savedInstanceState == null) { mFragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction(); FragmentOne fragment = new FragmentOne(); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit(); } 

Cuando se produce un cambio de configuración, el fragmento antiguo no se destruye: se añade a la actividad cuando se vuelve a crear.

  • LocalBroadcastManager y el ciclo de vida de la actividad
  • Android: cuando usar onStart (), onStop ()?
  • Actividad con servicio duradero en el fondo que no se matará
  • Diferencia principal entre el Manifiesto y el Registro Programático de BroadcastReceiver
  • Principiante de Android: onDestroy
  • ¿Cuándo puedo primero medir una vista?
  • Ver ciclo de vida del paginador y del fragmento
  • Fragmento ciclo de vida: cuando "ondestroy" y "ondestroyview" no son llamados?
  • Uso del servicio como singleton en Android
  • Cuándo llamar a super.onPause ()?
  • Liberar recursos en onPause en lugar de onDestroy
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.