2012-03-02 14 views
47

En mi aplicación hay una variable estática que se establece en nulo cuando regreso a mi aplicación desde el navegador externo. Parece que la aplicación o una parte de ella se elimina si la página web externa que estoy iniciando es lo suficientemente compleja.variable estática null al volver a la aplicación

Si la aplicación fuera eliminada por completo y luego relatada desde la actividad principal, estaría bien, pero el relanzamiento es de la actividad que inició el navegador, y no tiene por objeto configurar el estado de la aplicación al estrellarse al acceder la variable estática nula Este es un problema de dispositivo de uno de cada seis, así que necesito algunos consejos.

¿Hay un indicador para establecer para evitar este comportamiento?

+0

"Si la aplicación fuera eliminada por completo y luego relatada de la actividad principal que estaría bien ..." - En ese caso, simplemente cree una clase que extienda 'Aplicación' y mantenga allí la variable estática. – Squonk

+2

Entonces, ¿hay alguna diferencia en el alcance de una estática si está en Application.java o en algún otro? – jchristof

+0

@jchristof es demasiado tarde pero el campo estático de la aplicación no hará la diferencia – oscarthecat

Respuesta

33

Este es el comportamiento estándar en la mayoría de los sistemas operativos móviles, definitivamente incluye Android. Su aplicación es, de hecho, muy a menudo muere si alguna otra aplicación con mayor prioridad (en general, si está en primer plano es de mayor prioridad) necesita los recursos. Esto se debe a la naturaleza de los dispositivos móviles que tienen recursos relativamente limitados.

Debe guardar sus datos en un lugar más duradero. Puede encontrar este artículo en general Data Storage para ser útil. Esta pregunta también debería ser relevante: Saving Android Activity state using Save Instance State

Tenga en cuenta que esto es de hecho no un problema de dispositivo de uno de seis. Este es un "problema" en todos los dispositivos, es más evidente en uno de sus dispositivos, probablemente porque tiene menos memoria. Si ejecuta una aplicación que requiere mucha memoria en cualquiera de sus otros dispositivos, debería ver el mismo comportamiento. Además, no hay una bandera para evitar esto. Esto es estándar y esperado.

+0

Ok, esta afirmación es cierta en todos los casos: "Todas las actividades en el manifiesto de una aplicación deben ser la actividad de inicio para iniciar la aplicación". – jchristof

+0

No. Si su aplicación muere mientras está en segundo plano en la Actividad B, mientras que la Actividad A es la actividad principal de inicio en su aplicación, entonces se iniciará la Actividad A cuando reinicie la aplicación. También puede encontrar [este documento] (http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle) informativo. – kabuko

+0

Estoy confundido en este punto porque todo esto sucede en este caso: la Actividad B inicia el navegador nativo. Atrás del navegador onCreate() de la actividad B (no onResume()). La variable estática es nula que era válida hasta el momento de iniciar el navegador. – jchristof

4

No ... no debe almacenar datos en variables estáticas en android. Si insistes en hacerlo, deberás poder recuperarlo cuando sea nulo ... deberías guardar tu estado con paquetes u otros medios.

0

Probablemente solo quieras seguir el segundo enlace por kabuko. Pero si quiere mantener su variable estática (tal vez usted tiene alguna gran razón para esto), usted puede hacer esto:

private static MyObjType getVariable() 
{ 
    if (myVar == null) 
    myVar = new MyObjType(); // do whatever else you need to here 

    return myVar; 
} 

De esta forma se puede reemplazar las llamadas a myVar.test() con getVariable(). test() y usted sabe que nunca causará una excepción de puntero nulo.

+1

Esto tiene condiciones de carrera –

4

La solución a usar en Android de estática (de Singleton) es muy fácil:

implementar una clase que se extiende android.app.Application y hacer todo su inicialización Singleton dentro onCreate()

Razonamiento:

  • la clase que se extiende La aplicación se ejecuta primero, incluso cuando el proceso de su aplicación se cancela debido a una condición de memoria baja
  • su aplicación tiene contexto tan pronto s Application.onCreate() se llama
+1

la clase que extiende Aplicación * se ejecuta * primero ?? ¿Qué significa ejecutar? Además, ¿puede proporcionar documentos para este reclamo? –

+0

también agréguelos para manifestar como Qamar

0

Utilice la clase de aplicación para tales cosas. Siempre se crea una instancia antes de que comience cualquier componente (actividades, servicios, receptores) de su aplicación. Entonces, está seguro de que todas las variables estáticas están ahí e inicializadas.

1

Debe guardar sus valores en onSaveInstanceState y volver a obtenerlos en onRestoreInstanceState porque cuando una actividad pasa al ciclo de vida de estado detenido, todos los valores estáticos serán nulos.

por ejemplo:

 /* save my satatic hashmap in case of activity stopped to retrieve it again in onRestoreInstanceState method*/ 
     @Override 
     protected void onSaveInstanceState(Bundle outState) { 
      super.onSaveInstanceState(outState); 

    //Common.PERMISION_MAP static hashmap 
      if (Common.PERMISION_MAP != null) { 
       Iterator<Permission> iterator = Common.PERMISION_MAP.values() 
         .iterator(); 
       ArrayList<Permission> permissionList = new ArrayList<Permission>(); 
       while (iterator.hasNext()) { 
        Permission permission = (Permission) iterator.next(); 
        permissionList.add(permission); 

       } 
       outState.putParcelableArrayList("PERMISSION_LIST", permissionList); 
      } 


     } 

     /* restore my satatic hashmap when activity stopped */ 
     @Override 
     protected void onRestoreInstanceState(Bundle savedInstanceState) { 
      super.onRestoreInstanceState(savedInstanceState); 

      try { 
       ArrayList<Permission> permissionList = savedInstanceState 
         .getParcelableArrayList("PERMISSION_LIST"); 

       if (Common.PERMISION_MAP == null) 
        Common.PERMISION_MAP = new HashMap<Permission, Permission>(); 
for (Permission permission : permissionList) { 
       Common.PERMISION_MAP.put(permission, permission); 

      } 
       } catch (Exception ex) { 
       String string = ex != null ? ex.getMessage() : ""; 
       Log.e(TAG, (string != null ? string : "")); 
       ex.printStackTrace(); 

      } 
     } 
17

lo general, esto sucede cuando el dispositivo entra en modo de sueño .

Este comportamiento del dispositivo puede ser emulado por los siguientes pasos:

  1. Ejecutar la aplicación y pulse el botón Inicio
  2. En Android Studio en la esquina inferior izquierda, seleccione depurar la aplicación y presione el botón X (finalizar aplicación) a la izquierda del nombre de la aplicación. (No sé cómo Eclipse, pero creo que de manera similar)
  3. Haga clic en el icono de la aplicación en el dispositivo.

si la tarea era la actividad, la aplicación se abrirá en la última actividad y (lo más probable) generará un error, porque todas las variables estáticas se han de hojas.

+1

Esto es útil para reproducir los pasos. Ahora la depuración de la aplicación está categorizada en la pestaña ** Android Monitor **. –

+0

¿Qué hay de las variables no estáticas? –

Cuestiones relacionadas