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.
- Fragmento no invoca onSaveInstanceState al pasar ViewPager?
- Dejar la aplicación de Android con el botón Atrás
- Transición de la actividad: Realización de la parada de la actividad que no se reanuda
- La mejor manera de implementar Socket.io en android
- ¿Cómo puedo comprobar en Robotium que la aplicación ha terminado?
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.
- ¿Cómo evito que Android tome una captura de pantalla cuando mi aplicación va al fondo?
- Una Actividad y todos los otros Fragmentos
- OnCreate (Bundle savedInstanceState) en siempre nulo
- Cuándo usar y cuándo no utilizar un servicio en Android
- ¿Debe la llamada al método de superclase ser la primera instrucción?
- Mide la vista en el fragmento
- Diferenciar entre Android matando la aplicación y el usuario deslizarlo en la lista de aplicaciones recientes
- Los fragmentos de ViewPager no se recrean después de FragmentTransaction.replace () seguido por el botón de retroceso
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.
- Subir imágenes con FTP en Android
- Cómo eliminar fácilmente los recursos de localización innecesarios de bibliotecas añadidas en la versión APK