android - sirve - getApplication() vs. getApplicationContext()
para que sirve getapplicationcontext() (4)
No pude encontrar una respuesta satisfactoria a esto, así que aquí vamos: ¿cuál es el problema con Activity/Service.getApplication()
y Context.getApplicationContext()
?
En nuestra aplicación, ambos devuelven el mismo objeto. Sin embargo, en un ActivityTestCase
, simular la aplicación hará que getApplication()
vuelva con el simulacro, pero getApplicationContext
aún devolverá una instancia de contexto diferente (una inyectada por Android). ¿Es eso un error? ¿Es a propósito?
Ni siquiera entiendo la diferencia en primer lugar. ¿Hay casos fuera de un conjunto de pruebas donde ambas llamadas pueden regresar con diferentes objetos? ¿Cuándo y por qué? Además, ¿por qué se define getApplication
en Activity
y Service
, pero no en Context
? ¿No debería haber siempre una instancia de aplicación válida disponible desde cualquier lugar ?
Compare getApplication()
y getApplicationContext()
.
getApplication
devuelve un objeto Application
que le permitirá administrar el estado de su aplicación global y responder a algunas situaciones de dispositivos como onLowMemory()
y onConfigurationChanged()
.
getApplicationContext
devuelve el contexto global de la aplicación; la diferencia con respecto a otros contextos es que, por ejemplo, Android puede destruir (o dejar de estar disponible) un contexto de actividad cuando finaliza su actividad. El contexto de la Aplicación permanece disponible todo el tiempo que exista el objeto de la Aplicación (que no está vinculado a una Activity
específica), por lo que puede usarlo para cosas como las Notifications que requieren un contexto que estará disponible por períodos más largos e independientes de los objetos de la interfaz de usuario transitorios.
Supongo que depende de lo que haga su código si estos pueden o no ser los mismos, aunque en un uso normal, espero que sean diferentes.
Para responder a la pregunta, getApplication () devuelve un objeto de aplicación y getApplicationContext () devuelve un objeto de contexto. En base a sus propias observaciones, supongo que el Contexto de ambos es idéntico (es decir, detrás de la escena, la clase de Aplicación llama a la última función para poblar la porción de Contexto de la clase base o tiene lugar alguna acción equivalente). Realmente no debería importar a qué función llamas si solo necesitas un contexto.
Parece que tiene que ver con el ajuste de contexto. La mayoría de las clases derivadas de Context
son en realidad un ContextWrapper
, que esencialmente delega en otro contexto, posiblemente con cambios por parte del contenedor.
El contexto es una abstracción general que admite la burla y el proxy. Dado que muchos contextos están vinculados a un objeto de duración limitada, como una Activity
, es necesario que exista una manera de obtener un contexto de mayor duración, para fines como el registro para futuras notificaciones. Eso se logra con Context.getApplicationContext()
. Una implementación lógica es devolver el objeto de Application
global, pero nada impide que una implementación de contexto devuelva un contenedor o proxy con una vida útil adecuada.
Las actividades y servicios están más específicamente asociados con un objeto de Application
. Creo que la utilidad de esto es que puede crear y registrar en el manifiesto una clase personalizada derivada de la Application
y estar seguro de que Activity.getApplication()
o Service.getApplication()
devolverá ese objeto específico de ese tipo específico, que puede convertir a su clase de Application
derivada y usar para cualquier propósito personalizado.
En otras palabras, se garantiza que getApplication()
devuelva un objeto de Application
, mientras que getApplicationContext()
es libre de devolver un proxy en su lugar.
Pregunta muy interesante. Creo que es principalmente un significado semántico, y también puede deberse a razones históricas.
Aunque en las implementaciones actuales de la Actividad y el Servicio de Android, getApplication()
y getApplicationContext()
devuelven el mismo objeto, no hay garantía de que esto siempre sea así (por ejemplo, en una implementación de un proveedor específico).
Por lo tanto, si desea que la clase de Aplicación que registró en el Manifiesto, nunca debe llamar a getApplicationContext()
y convertirla en su aplicación, ya que puede que no sea la instancia de la aplicación (que obviamente experimentó con el marco de prueba).
¿Por qué existe getApplicationContext()
en primer lugar?
getApplication()
solo está disponible en la clase de actividad y la clase de servicio, mientras que getApplicationContext()
se declara en la clase de contexto.
En realidad, eso significa una cosa: cuando se escribe un código en un receptor de difusión, que no es un contexto sino que se le da un contexto en su método onReceive, solo puede llamar a getApplicationContext()
. Lo que también significa que no se le garantiza tener acceso a su aplicación en un BroadcastReceiver.
Cuando mira el código de Android, ve que cuando se adjunta, una actividad recibe un contexto base y una aplicación, y esos son parámetros diferentes. getApplicationContext()
delega su llamada a baseContext.getApplicationContext()
.
Una cosa más: la documentación dice que en la mayoría de los casos, no es necesario subclasificar la aplicación:
Normalmente no hay necesidad de subclase de
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), a la función para recuperarlo se le puede dar unContext
que utiliza internamenteContext.getApplicationContext()
cuando se construye por primera vez el singleton.
Sé que esta no es una respuesta exacta y precisa, pero aún así, ¿responde eso a tu pregunta?