¿Los campos estáticos de las clases de actividad están garantizados para sobrevivir a un ciclo de creación / destrucción?

Con frecuencia me encuentro con el problema que tengo que preservar el estado entre varias invocaciones de una actividad (es decir, pasando por varios ciclos onCreate () / onDelete ()). Lamentablemente, el apoyo de Android para hacer eso es realmente pobre.

Como una forma fácil de preservar el estado, pensé que ya que la clase sólo se carga una vez por el cargador de clases, que sería seguro para almacenar los datos temporales que se comparte entre varias instancias de una actividad en un campo estático Bundle.

Sin embargo, ocasionalmente, cuando la instancia A crea el paquete estático y almacena los datos en él, entonces se destruye, y la instancia B intenta leer de él, el campo estático es repentinamente NULL.

¿No significa eso que la clase había sido removida y recargada por el cargador de clases mientras la actividad estaba pasando por un ciclo de creación / destrucción? ¿De qué otra manera un campo estático de repente podría convertirse en NULL cuando se refería a un objeto antes?

La primera parte de esta respuesta es muy antigua – vea a continuación la forma correcta de hacerlo

Puede utilizar el objeto Aplicación para almacenar objetos persistentes de la aplicación. Esta FAQ de Android también habla de este problema.

Algo como esto:

public class MyApplication extends Application{ private String thing = null; public String getThing(){ return thing; } public void setThing( String thing ){ this.thing = thing; } } public class MyActivity extends Activity { private MyApplication app; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); app = ((MyApplication)getApplication()); String thing = app.getThing(); } } 

El camino correcto :

Cuando esta respuesta fue escrita por primera vez, la documentación para el ciclo de vida de la actividad no era tan buena como lo es ahora. Lectura de estado de actividad de ahorro en el documento de actividad nos ayuda a entender cómo Android quiere que guardemos el estado. Esencialmente, hay dos circunstancias bajo las cuales su actividad comienza: (1) como una nueva actividad y (2) debido a un cambio de configuración o cuando es recreada después de ser destruida debido a la presión de la memoria. Cuando su actividad se inicia porque es una nueva actividad, entonces saveInstanceState es null. No es nulo de lo contrario. Si es nulo, entonces su actividad debe inicializarse desde cero. Los fragmentos son muy similares a las actividades, y cubrieron este concepto en detalle para mi AnDevCon-14 cubierta de diapositivas . También puede echar un vistazo al código de ejemplo para mi presentación de AnDevCon-14 para más detalles.

Volver a trabajar mi ejemplo anterior sería algo como el código de abajo. Yo cambio la semántica un poco – en esta segunda versión supongo que la cadena es específica de la actividad dentro de una tarea android específica, en el ejemplo anterior es ambigua. Si desea mantener los mismos datos para varias tareas de Android, a continuación, utilizar el objeto de aplicación u otro singleton sigue siendo la mejor opción.

 public class MyActivity extends Activity { private static final String THING = "THING"; private String thing; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState==null) { // First time here (since we last backed out at least) thing = initializeThing(); // somehow we init it } else { // Rehydrate this new instance of the Activity thing = savedInstanceState.getString(THING); } String thing = app.getThing(); } protected void onSaveInstanceState(Bundle outState) { outState.putString(THING, thing); } } 

La otra manera, también malvada, de mantener datos estáticos es tener actividad en una clase singleton. Este singleton mantendría una referencia estática a sí mismo.

 class EvilSingleton{ private static EvilSingleton instance; //put your data as non static variables here public static EvilSingleton getInstance() { if(instance == null) instance = new EvilSingleton(); return instance; } } 

En el método onCreate () de su actividad puede acceder / construir el singleton y cualquier información que pueda necesitar. De esta forma, su actividad o aplicación puede ser destruida o recreada cualquier número de veces y siempre y cuando el espacio de memoria de su proceso se mantenga debe estar bien.

Este es un hack subversivo mal, por lo que no hay promesas 😉

  • ¿Cómo puedo obtener un contenido de recursos desde un contexto estático?
  • ¿Debo usar estática o getters / setters?
  • ¿Cómo usar esta palabra clave en un método estático en java?
  • Adaptador de matriz estática en fragmento. ¿Buenas o malas prácticas?
  • Android: getString (R.string) en el método estático
  • Método estático sin nombre
  • No se puede hacer referencia estática al método no estático (Android getApplicationContext ())
  • Ciclo de vida del objeto estático de Android
  • ¿Vive la variable estática incluso después de que la aplicación se cierre?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.