¿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.

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:

  1. ¿Por qué no fue así con Activities desde el principio.
  2. ¿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; } } 

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.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.