2012-04-21 13 views
41

Sé que el uso de variables estáticas en Android es bastante arriesgado, especialmente si los referencia a actividades. Sin embargo, si tengo una clase que extienda la Aplicación (llamemos a esta clase "Aplicación"), ¿es seguro hacer referencia a la instancia de esta clase?¿Es seguro guardar el contexto de la aplicación en una variable estática en Android?

Si es así, ¿también es seguro para cualquier otra clase tener algún tipo de referencia en el contexto de la aplicación? Quiero decir, ¿puede haber una pérdida de memoria si tengo una referencia al contexto de la aplicación en cualquier clase de clase?

El propósito es que no importa en qué alcance me encuentre, siempre puedo obtener una referencia al contexto de la aplicación. Creo que es seguro, ya que si el sistema cierra la aplicación, la variable estática también se va hasta la próxima vez que la aplicación se inicia nuevamente, lo que inicializará la variable estática nuevamente.

Además, no es que importe demasiado, pero si utilizo procesos múltiples, ¿obtendré referencias totalmente diferentes a la clase de la aplicación en cada proceso?

Como ejemplo de código, esto es lo que estoy pensando:

public class App extends Application 
{ 
    private static Context _appContext; 

    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
     _appContext = this; 
    } 

    public static Context getAppContext() 
    { 
     return _appContext; 
    } 
} 
+0

duplicado? https://stackoverflow.com/questions/2002288/static-way-to-get-context-on-android –

+1

@YoushaAleayoub No. La pregunta es si es seguro. No si es posible y cómo hacerlo. Ya he demostrado cómo hacerlo. –

Respuesta

27

¿es seguro para guardar el contexto de aplicación para una variable estática?

En la actualidad, sí, parece ser seguro, aunque no tendría retorno getAppContext()Context, pero en su lugar volver App o Application.

Dicho esto, el hecho de que el equipo principal de Android no lo haya configurado de esta manera en primer lugar sugiere que tal vez haya problemas ocultos de los que no tenemos conocimiento, o que en el futuro este enfoque pueda presentar problemas .

Como el acrónimo del refrán va, YMMV. :-)


EDITAR

si es así, es también seguro para cualquier otra clase que tenga cualquier tipo de referencia al contexto de aplicación?

No tengo ni idea de lo que quieres decir con "seguro" aquí.

pero si utilizo procesos múltiples, obtendré referencias totalmente diferentes a la clase de la aplicación en cada proceso, ¿verdad?

Si usa procesos múltiples, debe recibir una bofetada. Pero, sí, debe obtener distintas instancias App por proceso.

+0

entonces, ¿puede pensar en alguna forma que se encargue de posibles problemas? ¿Debo usar WeakReference en lugar de una referencia difícil? también, intente responder el resto de las preguntas. –

+1

@androiddeveloper: "¿Puedes pensar en alguna forma que solucione los posibles problemas?" - dado que no sabemos cuáles son los posibles problemas, es imposible diseñar una solución para ellos. – CommonsWare

+0

También pensé en tu enfoque hace algún tiempo, ya que no es cómodo pasar de contexto cada vez ... Supongo que inicializas esta variable estática de tu actividad principal, ¿estoy en lo cierto? – Caumons

7

Debe ser seguro. También la siguiente nota de la API docs podría ser relevante para usted:

Normalmente no hay necesidad de subclase Application. En la mayoría de las situaciones, los singletons estáticos pueden proporcionar la misma funcionalidad de una manera más modular .Si su singleton necesita un contexto global (por ejemplo, para registrar receptores de difusión ), la función para recuperarlo puede tener un contexto que internamente usa Context.getApplicationContext() cuando construye primero el singleton.

+0

sí. ¿Es cierto que las variables estáticas funcionan de forma extraña en Android? por ejemplo, si la aplicación usa demasiada memoria, algunas clases se descargarán, de modo que si contienen variables estáticas, ¿se habrán ido también? –

+0

@Nate, tenga a bien hacer alguna referencia a cualquier sitio web de Google que diga que funciona de esta manera.algunos desarrolladores afirman que funciona de esta manera y algunos dicen que no (como el usuario CommonsWare). así que este es un tema muy confuso. –

+0

@androiddeveloper, no conseguí esto en un sitio web. Obtuve la información probando en dispositivos reales, que es una referencia más sólida que cualquier otra documentación. Aquí hay una muestra de cómo reproducir dicho comportamiento. Obtenga una herramienta que le permita limpiar memoria manualmente. Por ejemplo "Go TaskManager EX". Ejecuta tu aplicación. Presiona el botón de inicio Limpie la memoria. Regrese a su aplicación en el depurador. Observe las variables estáticas en el depurador. Por cierto, he visto esto en dispositivos sin ejecutar Go TaskManager. Es solo que si quiere ver algo repetible, de inmediato, necesita barrer la memoria usted mismo. – Nate

2

Es seguro hacer esto en Application#onCreate() porque el Application se crea antes de cualquier actividad. Si se mata a tu aplicación en segundo plano, se volverá a crear la instancia Application y se establecerá tu global antes de que se ejecute cualquier actividad.

Es importante tener en cuenta que nunca debe establecer variables globales de una actividad. Si lo hace, su aplicación podría fallar en la siguiente forma:

  1. conjunto global de la actividad Un
  2. Vaya a la actividad B
  3. aplicación entra en el fondo
  4. Marco mata aplicación y el proceso de
  5. App se restaura
  6. El marco crea actividad B. Las actividades en la pila posterior no se crean hasta que vuelva a navegar hacia ellas, ¡entonces no se establece el global!
  7. Actividad B intenta usar mundial, y el auge ... NullPointerException
1

Interesante comentario apareció de estudio cuando estaba ordenando contextos estáticos desagradables:

"Se trata de una fuga (y también rompe la ejecución instantánea) ".

Así que con el lanzamiento de Instant Run, tenemos el caso donde los desarrolladores de Android no planean guardar variables estáticas. Aunque la ejecución instantánea no está (todavía) en mi agenda, es útil saber que hay un ejemplo específico donde no solo se trata de una mala práctica, sino que también se identifica el caso de uso en el que está equivocado.

Cuestiones relacionadas