¿Por qué querría alguna vez `setRetainInstance (false)`? – O – La forma correcta de manejar la rotación del dispositivo
Por favor, corrija si estoy equivocado en algo de esto. Esta es una especie de pregunta aclaratoria, ya que no la he visto explícitamente escrita en ninguna parte.
En Android 4, puedes llamar a setRetainInstance(true)
en un Fragment
para que en los cambios de configuración (que básicamente significa rotación del dispositivo), el objeto Fragment
java no se destruya y no se cree una nueva instancia del mismo. Es decir, la instancia se conserva.
- Ejecutar código justo después de que un fragmento se vuelve visible por primera vez
- Ciclo de vida de Android: rellena datos en actividad en onStart () o onResume ()?
- ¿Los fragmentos con setRetainInstance (true) sobreviven al cierre del proceso?
- Ciclo de vida de la clase de aplicación mientras se ejecuta el servicio
- Android: ¿En qué circunstancias podría aparecer un diálogo que cause onPause ()?
Esto es mucho más sano y menos enfurecedor que en Android 1-3, ya que no tiene que tratar con onRetainNonConfiguration
State
Instance()
y agrupar todos sus datos para que pueda pasar a la nueva Fragment
(o Activity
) instancia sólo para Se desagregarán de nuevo. Es básicamente lo que usted esperaría que suceda, y discutiblemente cómo debe haber trabajado para la Activity
s desde el principio.
Con setRetainInstance(true)
la vista también se onCreateView()
crear ( onCreateView()
se llama) en rotación como se esperaría. Y supongo (no probado) que la resolución de recursos ( layout
vs layout-land
) funciona.
Así que mi pregunta es doble:
- ¿Por qué no fue así con
Activities
desde el principio. - ¿Por qué no es el predeterminado? ¿Alguna vez hay alguna razón por la que realmente quieren que su
Fragment
sea inútilmente destruido y recreado en rotación? Porque no puedo pensar en ninguno.
Editar
Para aclarar cómo lo haría:
class MyFragment extends Fragment { // All the data. String mDataToDisplay; // etc. // All the views. TextView mViewToDisplayItIn; // etc. @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); mDataToDisplay = readFromSomeFileOrWhatever(); // Ignoring threading issues for now. } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.my_fragment, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { // At this point if mViewToDisplayItIn was not null, the old one will be GC'd. mViewToDisplayItIn = view.findViewById(R.id.the_text_view); mViewToDisplayItIn.setText(mDataToDisplay); } // Optionally: @Override public void onDestroyView() { // All the view (and activity) to be GC'd. mViewToDisplayItIn = null; } }
- Android Fragment onCreateView después de onDestroy no se vuelve a llamar
- Parámetro startId de servicio de Android
- Servicios de Android: consideraciones sobre el ciclo de vida
- ¿Por qué podemos llamar a getActivity () en onCreateView que se ejecuta antes onActivityCreated?
- Reiniciar el fragmento dentro de la actividad
- SQLite o SharedPreferences para el almacenamiento de datos persistentes?
2 Solutions collect form web for “¿Por qué querría alguna vez `setRetainInstance (false)`? – O – La forma correcta de manejar la rotación del dispositivo”
De modo que en los cambios de configuración (que básicamente significa la rotación del dispositivo)
Cambiar la configuración regional, cambiar SIMs, cambiar el tamaño predeterminado de la fuente, conectar o quitar un teclado externo, colocar el dispositivo en un muelle o eliminarlo del mismo, etc.
Usted no tiene que tratar con onRetainNonConfigurationState ()
Eso es onRetainNonConfigurationInstance()
.
Agrupe todos sus datos para que puedan ser pasados a la nueva instancia de Fragmento (o Actividad) sólo para desagregarse de nuevo
Sus datos ya deberían estar "empaquetados" (por ejemplo, instancia de clase interna privada estática) y, por lo tanto, no tendrían que estar "agrupados" o "desagregados". Además, con frecuencia no debe ser "todos sus datos", a menos que sea un fan de fugas de memoria.
Y supongo (no probado) que la resolución de recursos (diseño vs diseño de la tierra) funciona.
Correcto.
¿Alguna vez hay alguna razón por la que realmente quieren que su Fragmento sea inútilmente destruido y recreado en rotación?
Por supuesto.
Como observas, todos los widgets se recrean, por lo que los miembros de los datos vinculados a los widgets no solo son innecesarios de retener. A menos que específicamente los restablezca a null
en un fragmento retenido de alguna manera, hasta que se onCreateView()
, esos miembros de datos se mantendrían en los antiguos widgets, que se mantendrían en la antigua instancia de actividad, lo que evitaría que la antigua instancia de actividad fuera de basura recogido. AFAIK, onCreateView()
no va a ser llamado hasta que el fragmento se va a volver a mostrar, lo que puede no ser durante bastante tiempo (el fragmento no se utiliza en la nueva orientación, o el fragmento es para alguna página en un ViewPager
que El usuario visitó en la orientación antigua pero no revisita en la nueva orientación, etc.). Esto significa que el fragmento retenido puede mantener el antiguo objeto de actividad durante un período de tiempo sustancial. Dependiendo de qué otra actividad haya retenido (por ejemplo, objetos de Bitmap
grandes), eso podría ser malo.
Del mismo modo, un fragmento que se detiene en datos grandes, donde ese fragmento puede o no puede ser usado después del cambio de configuración, es uno que no debe ser retenido.
Además, habrá fragmentos que simplemente no tienen que ser retenidos (por ejemplo, todos los datos están ocupados por Loaders
, que ya son conscientes de los cambios de configuración y los manejan apropiadamente).
Y así.
Un defecto de fragmentos que no se retiene es el curso de acción más seguro, con respecto a los problemas de recolección de basura. Usted puede optar por tener algunos fragmentos ser retenido, pero entonces la responsabilidad es en usted para asegurarse de que no se está atornillando a ti mismo haciendo eso.
No sé la respuesta a la primera pregunta. Debería haber sido así desde el principio. Supongo que alguien en Google pensó que son realmente inteligentes venir con este esquema.
La segunda pregunta, sin embargo, es mucho más fácil. Este no es el valor predeterminado porque esto no es lo que Android desarrolla han aprendido a esperar. Android desarrolla saber que la instancia muere en rotación y lo espera. Cambiar el valor por defecto habría hecho que muchos desarrolladores estuvieran realmente enojados.