getApplication () frente a getApplicationContext ()

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 , burlarse de la aplicación hará que getApplication() vuelva con el simulacro, pero getApplicationContext 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 banco de pruebas donde ambas llamadas pueden regresar con diferentes objetos? ¿Cuándo y por qué? Además, ¿por qué se define getApplication en Activity and Service , pero no en Context ? ¿No debería haber siempre una instancia de aplicación válida disponible desde cualquier 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 actividad y servicio de Android, getApplication() y getApplicationContext() devuelven el mismo objeto, no hay garantía de que este sea siempre el caso (por ejemplo, en una implementación de proveedor específica).

Entonces, si desea la clase de Aplicación que registró en el Manifiesto, nunca debe llamar a getApplicationContext() y getApplicationContext() a su aplicación, ya que puede no ser la instancia de la aplicación (que obviamente experimentó con el marco de prueba).

¿Por qué getApplicationContext() existe en primer lugar?

getApplication() solo está disponible en la clase Activity y en la clase Service, mientras que getApplicationContext() se declara en la clase Context.

Eso en realidad significa una cosa: cuando se escribe 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 se puede llamar a getApplicationContext() . Lo que también significa que no tiene garantizado el acceso a su aplicación en un BroadcastReceiver.

Al mirar el código de Android, verá 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 debería necesitar la subclase Aplicación:

Normalmente no hay necesidad de subclasificar la Application . En la mayoría de las situaciones, los singleton 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 Context que internamente utiliza Context.getApplicationContext() cuando construye el singleton por primera vez.

Sé que esta no es una respuesta exacta y exacta, pero aún así, ¿responde eso a tu pregunta?

Compare getApplication() y getApplicationContext() .

getApplication devuelve un objeto Application que le permitirá administrar su estado de aplicación global y responder a algunas situaciones de dispositivos como onLowMemory() y onConfigurationChanged() .

getApplicationContext devuelve el contexto de la aplicación global: la diferencia con respecto a otros contextos es que, por ejemplo, Android puede destruir un contexto de actividad (o dejarlo no disponible) cuando finalice su actividad. El contexto de la aplicación permanece disponible mientras su objeto Application existe (que no está vinculado a una Activity específica) por lo que puede usarlo para cosas como Notifications que requieren un contexto que estará disponible por períodos más largos e independientemente de los objetos UI transitorios.

Supongo que depende de lo que haga su código, ya sea que estos puedan ser o no iguales, aunque en el uso normal, espero que sean diferentes.

Parece que tiene que ver con el ajuste del contexto. La mayoría de las clases derivadas de Context son en realidad ContextWrapper , que esencialmente se delegan en otro contexto, posiblemente con cambios en el contenedor.

El contexto es una abstracción general que admite el burlarse y el proxy. Dado que muchos contextos están ligados a un objeto de duración limitada, como una Activity , es necesario que haya una forma de obtener un contexto de mayor duración, para fines tales como registrarse para futuras notificaciones. Eso se logra mediante Context.getApplicationContext() . Una implementación lógica es devolver el objeto Application global, pero nada impide que una implementación de contexto devuelva un contenedor o un proxy con una duración adecuada.

Las actividades y los servicios están más específicamente asociados con un objeto Application . La utilidad de esto, creo, es que puede crear y registrar en el manifiesto una clase personalizada derivada de la Application y asegurarse 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 usarla para cualquier propósito personalizado.

En otras palabras, se garantiza que getApplication() devolverá un objeto Application , mientras que getApplicationContext() puede devolver un proxy en su lugar.

Para responder a la pregunta, getApplication () devuelve un objeto Application y getApplicationContext () devuelve un objeto Context. En base a sus propias observaciones, supondría que el contexto de ambos es idéntico (es decir, detrás de escena, la clase de aplicación llama a la última función para poblar la parte de contexto de la clase base o se produce alguna acción equivalente). Realmente no debería importar a qué función llamar si solo necesita un Contexto.