getApplicationContext()
Casi siempre está mal. La Sra Hackborn (entre otros) han sido muy explícita que sólo se utiliza getApplicationContext()
cuando se sabe por qué está utilizando getApplicationContext()
y sólo cuando se necesita utilizar getApplicationContext()
.
Para ser franco, "algunos programadores" usan getApplicationContext()
(o getBaseContext()
, en menor medida) porque su experiencia en Java es limitada. Implementan una clase interna (por ejemplo, an OnClickListener
para a Button
en an Activity
) y necesitan a Context
. En lugar de usar MyActivity.this
para llegar a la clase externa ' this
, usan getApplicationContext()
o getBaseContext()
para obtener un Context
objeto.
Usted sólo se utiliza getApplicationContext()
cuando se sabe que necesita un Context
algo que puede vivir más tiempo que cualquier otro probable que Context
usted tiene a su disposición. Los escenarios incluyen:
Úselo getApplicationContext()
si necesita algo vinculado a un elemento Context
que tenga alcance global. Yo uso getApplicationContext()
, por ejemplo, en WakefulIntentService
, para la estática WakeLock
que se utilizará para el servicio. Como eso WakeLock
es estático y necesito un Context
método PowerManager
para crearlo, es más seguro usarlo getApplicationContext()
.
Úselo getApplicationContext()
cuando se une a a Service
desde an Activity
, si desea pasar el ServiceConnection
(es decir, el identificador al enlace) entre Activity
instancias a través de onRetainNonConfigurationInstance()
. Android realiza un seguimiento interno de los enlaces a través de estos ServiceConnections
y contiene referencias a los Contexts
que crean los enlaces. Si se vincula desde Activity
, entonces la nueva Activity
instancia tendrá una referencia a la ServiceConnection
que tiene una referencia implícita a la anterior Activity
, y la antigua Activity
no se puede recolectar basura.
Algunos desarrolladores utilizan subclases personalizadas Application
para sus propios datos globales, que recuperan a través de getApplicationContext()
. Eso es ciertamente posible. Prefiero miembros de datos estáticos, si no es por otra razón que solo puede tener unApplication
objeto personalizado . Creé una aplicación usando un Application
objeto personalizado y me pareció doloroso. La Sra. Hackborn también está de acuerdo con esta posición .
Aquí hay razones por las que nogetApplicationContext()
debes usar donde sea que vayas:
No es completo Context
, apoya todo lo que Activity
hace. Fallarán varias cosas que intentará hacer con esto Context
, principalmente relacionadas con la GUI .
Puede crear pérdidas de memoria, si el Context
retenido getApplicationContext()
retiene algo creado por sus llamadas que no limpia. Con un Activity
, si se aferra a algo, una vez que Activity
se recolecta la basura, todo lo demás también se elimina. El Application
objeto permanece durante toda la vida de su proceso.
getApplicationContext()
cuando sabe exactamente por qué lo necesita en una situación determinada. ¿Inflar un diseño? Usa la actividad. Enlace a un servicio, ¿dónde necesita ese enlace para sobrevivir a un cambio de configuración? UsegetApplicationContext()
, por lo que el enlace no está vinculado a laActivity
instancia.Creo que hay muchas cosas que están mal documentadas en el sitio del SDK, esta es una de ellas. La afirmación que haré es que parece que es mejor usar el contexto de una aplicación por defecto y solo usar un contexto de actividad cuando realmente lo necesite. El único lugar donde he visto que necesitas un contexto de actividad es para un diálogo de progreso. SBERG412 afirma que tiene que usar un contexto de actividad para un mensaje brindis, sin embargo, los documentos de Android muestran claramente el contexto de una aplicación que se está utilizando. Siempre he usado el contexto de la aplicación para brindar por este ejemplo de Google. Si está mal hacerlo, Google dejó caer la pelota aquí.
Aquí hay más para pensar y revisar:
Para un mensaje de brindis, la Guía de desarrollo de Google usa el contexto de la aplicación y dice explícitamente que se use: Notificaciones de brindis
En la sección de diálogos de la guía de desarrollo, verá que un AlertDialog.Builder usa el contexto de la aplicación, y luego la barra de progreso usa un contexto de actividad. Google no lo explica. Cuadros de diálogo
Parece que una buena razón para usar el contexto de la aplicación es cuando desea manejar los cambios de configuración como un cambio de orientación, y desea retener objetos que necesitan un contexto como Vistas. Si mira aquí: Cambios en el tiempo de ejecución Hay una advertencia sobre el uso de un contexto de actividad, que puede crear una fuga. Esto se puede evitar con un contexto de aplicación con las vistas que se deben conservar (al menos eso entiendo). En una aplicación que estoy escribiendo, tengo la intención de usar un contexto de aplicación porque estoy tratando de mantener algunas vistas y otras cosas en un cambio de orientación, y todavía quiero que la actividad sea destruida y recreada en los cambios de orientación. Por lo tanto, tengo que usar un contexto de aplicación para no causar una pérdida de memoria (consulte Cómo evitar pérdidas de memoria) Para mí, parece que hay muchas buenas razones para usar el contexto de la aplicación en lugar de un contexto de actividad, y para mí casi parece que lo usarías con más frecuencia que un contexto de actividad. Eso es lo que parecen hacer muchos libros de Android por los que he pasado, y eso es lo que hacen muchos de los ejemplos de Google que he visto.
La documentación de Google realmente hace que parezca que usar el contexto de la aplicación está perfectamente bien en la mayoría de los casos, y de hecho aparece con más frecuencia que usar un contexto de actividad en sus ejemplos (al menos los ejemplos que he visto). Si realmente es un problema usar el contexto de la aplicación, entonces Google realmente necesita poner más énfasis en esto. Necesitan dejarlo en claro, y necesitan rehacer algunos de sus ejemplos. No atribuiría esto completamente a los desarrolladores inexpertos ya que la autoridad (Google) realmente hace que parezca que no es un problema usar contextos de aplicación.
fuente
Utilicé esta tabla como guía sobre cuándo usar los diferentes tipos de contexto, como el contexto de la aplicación (es decir:)
getApplicationContext()
y el contexto de actividad , también el contexto de BroadcastReceiver :Todos los méritos van al autor original aquí para obtener más información.
fuente
Hay dos tipos de contexto:
El contexto de la aplicación está asociado con la aplicación y siempre será el mismo durante toda la vida de la aplicación; no cambia. Entonces, si está usando Toast, puede usar el contexto de la aplicación o incluso el contexto de la actividad (ambos) porque el toast se puede mostrar desde cualquier lugar de su aplicación y no está adjunto a una ventana específica. Pero hay muchas excepciones, una excepción es cuando necesita usar o pasar el contexto de actividad.
El contexto de actividad está asociado a la actividad y puede destruirse si se destruye la actividad; puede haber múltiples actividades (más que probable) con una sola aplicación. Y a veces necesitas absolutamente el manejo del contexto de actividad. Por ejemplo, si inicia una nueva actividad, debe usar el contexto de actividad en su Intención para que la nueva actividad de inicio esté conectada a la actividad actual en términos de pila de actividades. Sin embargo, también puede usar el contexto de la aplicación para iniciar una nueva actividad, pero luego debe establecer el indicador
Intent.FLAG_ACTIVITY_NEW_TASK
con la intención de tratarla como una nueva tarea.Consideremos algunos casos:
MainActivity.this
se refiere al contexto MainActivity que extiende la clase Activity pero la clase base (actividad) también extiende la clase Context, por lo que puede usarse para ofrecer el contexto de actividad.getBaseContext()
Ofrece contexto de actividad.getApplication()
Ofrece contexto de aplicación.getApplicationContext()
también ofrece contexto de aplicación.Para obtener más información, consulte este enlace .
fuente
downloadmanager
y, cuando se recibe la señal finalizada, debe mostrar un cuadro de diálogo, por ejemplo, "¿Qué desea hacer con esta descarga?". Mi solución (piratear) guarda la más recienteActivity
de unastatic
Application
clase y solicita la actualActivity
cuando se completa la descarga. Sin embargo, dudo que esta sea la implementación adecuada. TL; DR ¿Cómo mostrar AlertDialog en cualquier lugar de la aplicación?Me preguntaba por qué no usar Contexto de aplicación para cada operación que admite. Al final, reduce la posibilidad de pérdida de memoria y falta de verificación nula para getContext () o getActivity () (cuando se utiliza el contexto de aplicación inyectada o se adquiere a través del método estático de Aplicación). Las declaraciones, como la de la Sra. Hackborn para usar el contexto de la aplicación solo si es necesario, no me parecen convincentes sin una explicación de por qué. Pero parece que he encontrado una falta de ropa por qué:
¡Porque no está garantizado que todas las operaciones descritas como compatibles con el Contexto de aplicación en la tabla a continuación funcionen en todos los dispositivos Android!
fuente
Dos excelentes ejemplos de cuándo debe usar el contexto de actividad frente al contexto de la aplicación son cuando se muestra un mensaje Toast o un mensaje de diálogo incorporado, ya que el uso del contexto de la aplicación causará una excepción:
o
Ambos necesitan información del contexto Actividad que no se proporciona en el contexto Aplicación.
fuente
Contexto de aplicación en vivo hasta las que su aplicación está vivo única y es no depende de la actividad del ciclo de vida pero, el contexto objeto torreón de larga vida . Si el objeto que se usa temporalmente, ese tiempo, el Contexto de aplicación y el Contexto de actividad se usa totalmente opuesto al Contexto de aplicación.
fuente