¿Cuándo llamar al contexto de la actividad O contexto de la aplicación?
Ha habido un montón de publicar sobre lo que estos dos contextos son .. Pero todavía no lo estoy haciendo muy bien
Como yo lo entiendo hasta el momento: Cada una es una instancia de su clase, lo que significa que algunos programadores le recomendamos que use this.getApplicationContext()
tan a menudo como sea posible con el fin de no "escape" de cualquier memoria. Esto se debe a que el otro (obteniendo el contexto de la instancia de Activity
) apunta a una Activity
que se está destruyendo cada vez que el usuario inclina el teléfono o deja la aplicación etc. Lo que aparentemente el Recolector de Basura no captura y por lo tanto usa Demasiada memoria
- El contexto de la aplicación devuelve null cuando se utiliza getFilesDir ()
- ¿Qué significa exactamente usar el contexto de aplicación?
- Cómo llamar a getResources () de una clase que no tiene contexto?
- Error de Android escribiendo datos de ubicación en la base de datos SQLite de la clase LocationListener
- Cómo obtener el contexto de la aplicación
¿Pero puede alguien por favor venir con algunos ejemplos de codificación muy buenos donde sería la cosa correcta para usar this
(obtener el contexto de la instancia actual de la Activity
) y el contexto de la aplicación será inútil / mal?
- Context.registerReceiver devuelve una intención nula al intentar comprobar si la fuente de alimentación está conectada
- ¿Por qué ContextThemeWrapper está ahora restringido al grupo Support Library?
- Cómo pasar un contexto de actividad en una aplicación a un servicio en otra aplicación
- Método de llamada de otra clase usando contextos
- ¿Qué es "tools: context" en los archivos de diseño de Android?
- Android: Campos estáticos y fugas de memoria
- Acceso a DB con diferentes contextos
- Android DataBinding dónde obtener el contexto?
getApplicationContext()
casi siempre es incorrecto. La Sra. Hackborn (entre otras) ha sido muy explícita de que sólo usas getApplicationContext()
cuando sabes por qué usas getApplicationContext()
y solo cuando necesitas usar getApplicationContext()
.
Para ser contundente, "algunos programadores" utilizan getApplicationContext()
(o getBaseContext()
, en menor medida) porque su experiencia en Java es limitada. Implementan una clase interna (por ejemplo, un OnClickListener
para un Button
en una Activity
) y necesitan un Context
. En lugar de usar MyActivity.this
para obtener en la clase externa ' this
, utilizan getApplicationContext()
o getBaseContext()
para obtener un objeto Context
.
Sólo utiliza getApplicationContext()
cuando sabe que necesita un Context
para algo que puede vivir más tiempo que cualquier otro Context
probable que tenga a su disposición. Los escenarios incluyen:
-
Use
getApplicationContext()
si necesita algo vinculado a unContext
que por sí mismo tendrá alcance global. UtilizogetApplicationContext()
, por ejemplo, enWakefulIntentService
, para que elWakeLock
estático se utilice para el servicio. Dado queWakeLock
es estático, y necesito unContext
para llegar aPowerManager
para crearlo, es más seguro usargetApplicationContext()
. -
Utilice
getApplicationContext()
cuando vincula a unService
de unaActivity
, si desea pasar laServiceConnection
(es decir, el identificador a la vinculación) entre instancias deActivity
través deonRetainNonConfigurationInstance()
. Android internamente rastrea enlaces a través de estasServiceConnections
y contiene referencias a losContexts
que crean los enlaces. Si vincula desde laActivity
, la nueva instancia deActivity
tendrá una referencia a laServiceConnection
que tiene una referencia implícita a la antiguaActivity
, y la antiguaActivity
no se puede recolectar basura.
Algunos desarrolladores usan subclases personalizadas de Application
para sus propios datos globales, que recuperan a través de getApplicationContext()
. Eso es ciertamente posible. Prefiero los miembros de datos estáticos, si no por otra razón que sólo puede tener un objeto de Application
personalizada. Construí una aplicación utilizando un objeto Application
personalizado y encontré que era doloroso. La Sra. Hackborn también está de acuerdo con esta posición .
Aquí hay razones para no usar getApplicationContext()
donde quiera que vaya:
-
No es un
Context
completo, apoyando todo lo que hace laActivity
. Varias cosas que intentarás hacer con esteContext
fallarán, principalmente relacionadas con la GUI . -
Puede crear fugas de memoria, si el
Context
degetApplicationContext()
mantiene en algo creado por las llamadas en él que no limpia. Con unaActivity
, si se mantiene en algo, una vez que laActivity
recibe la basura recogida, todo lo demás se vacía también. El objetoApplication
permanece durante toda la vida de su proceso.
Creo que hay un montón de cosas que está mal documentado en el sitio SDK, este es uno de ellos. La afirmación que voy a hacer es que parece que es mejor usar el contexto de la aplicación y usar un contexto de actividad cuando realmente lo necesites. El único lugar donde he visto que necesitas un contexto de actividad es para un diálogo de progreso. SBERG412 afirma que tiene que utilizar un contexto de actividad para un mensaje de brindis, pero los documentos de Android muestran claramente un contexto de aplicación que se utiliza. Siempre he utilizado el contexto de aplicación para brindis debido a este ejemplo de Google. Si está mal hacerlo, entonces Google dejó caer el balón aquí.
Aquí hay más cosas que pensar y revisar:
Para un mensaje de brindis, la Guía de Google Dev utiliza el contexto de la aplicación y dice explícitamente que debe usarlo: Notificaciones Toast
En la sección de diálogos de la guía Dev, verá que un AlertDialog.Builder utiliza el contexto de la aplicación y, a continuación, la barra de progreso utiliza un contexto de actividad. Esto no se explica por Google. Diálogos
Parece que una buena razón para utilizar el contexto de la aplicación es cuando desea manejar cambios de configuración como un cambio de orientación y desea conservar objetos que necesitan un contexto como Vistas. Si miras aquí: Run Time Changes 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 opiniones que deben ser retenidas (al menos eso es lo que entiendo). En una aplicación que estoy escribiendo, tengo la intención de utilizar 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 se destruya y se recrea 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 Evitar fugas de memoria ). A mi me parece que hay un montón de buenas razones para utilizar el contexto de la aplicación en lugar de un contexto de actividad, y para mí casi parece que lo utilizaría más a menudo que un contexto de actividad. Eso es lo que muchos libros de Android que he pasado parecen hacer, y eso es lo que muchos de los ejemplos de Google que he visto hacer.
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 más a menudo 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 claro, y necesitan rehacer algunos de sus ejemplos. Yo no culparía esto totalmente a los desarrolladores sin experiencia, ya que la autoridad (Google) realmente hace que parezca que no es un problema para usar contextos de aplicación.
Acabo de utilizar esta tabla como una guía para cuando utilizar los diferentes tipos de Contexto como el contexto de la aplicación (es decir: getApplicationContext()
) y el contexto de la actividad , también BroadcastReceiver contexto :
Artículo original aquí para más información.
¿Qué contexto usar?
Hay dos tipos de Contexto:
-
El contexto de la aplicación se asocia con la aplicación y siempre será el mismo durante toda la vida de la aplicación – no cambia. Por lo tanto, si utiliza Toast, puede utilizar el contexto de la aplicación o incluso el contexto de la actividad (ambos) porque la tostada puede mostrarse desde cualquier lugar de la aplicación y no está asociada a una ventana específica. Pero hay muchas excepciones, una excepción es cuando se necesita usar o pasar el contexto de la actividad.
-
El contexto de la actividad está asociado con la actividad y puede ser destruido si la actividad es destruida – puede haber múltiples actividades (más que probable) con una sola aplicación. Y a veces es absolutamente necesario el identificador de contexto de actividad. Por ejemplo, si inicia una nueva actividad, debe utilizar el contexto de la actividad en su Intención para que la nueva actividad de lanzamiento se conecte a la actividad actual en términos de pila de actividades. Sin embargo, también puede utilizar el contexto de la aplicación para iniciar una nueva actividad, pero debe establecer el indicador
Intent.FLAG_ACTIVITY_NEW_TASK
con la intención de tratarlo como una nueva tarea.
Consideremos algunos casos:
-
MainActivity.this
refiere al contexto MainActivity que extiende la clase Activity pero la clase base (activity) también extiende la clase Context, por lo que se puede utilizar para ofrecer el contexto de la actividad. -
getBaseContext()
ofrece un contexto de actividad. -
getApplication()
ofrece un contexto de aplicación. -
getApplicationContext()
también ofrece contexto de aplicación.
Para obtener más información, consulte este enlace .
Dos grandes ejemplos de cuándo debe utilizarse el contexto de la actividad en comparación con el contexto de la aplicación son cuando se muestra un mensaje Toast o un mensaje de diálogo incorporado como utilizar el contexto de la aplicación provocará una excepción:
ProgressDialog.show(this, ....);
o
Toast t = Toast.makeText(this,....);
Ambos necesitan información del contexto de la actividad que no se proporciona en el contexto de la aplicación.
Contexto de la aplicación en vivo hasta que su aplicación sólo está viva y no depende del ciclo de vida de la actividad pero, el objeto de mantener el contexto de larga vida . Si el objeto que se utiliza temporalmente, ese uso de tiempo Contexto de la Aplicación y Contexto de la actividad se utiliza totalmente opuesto al Contexto de la Aplicación.
Me preguntaba por qué no utilizar el contexto de aplicación para cada operación que admite. Al final, disminuye la probabilidad de pérdida de memoria y falta la comprobación nula de getContext () o getActivity () (cuando se utiliza el contexto de aplicación inyectado o se adquiere mediante el método estático de Application). Declaraciones, como la de la Sra. Hackborn para usar el Contexto de la Aplicación sólo si es necesario, no me parecen convincentes sin una explicación de por qué. Pero parece que he encontrado un unswear por qué:
Han encontrado que hay problemas en algunas combinaciones de versión / dispositivo de Android que no siguen estas reglas. Por ejemplo, si tengo un BroadcastReceiver que se pasa un Contexto y convertir ese Contexto a un Contexto de Aplicación y luego intento llamar a registerReceiver () en el Contexto de la Aplicación hay muchos casos en los que esto funciona bien, pero también muchas instancias donde recibo Un bloqueo debido a un ReceiverCallNotAllowedException. Estos bloqueos se producen en una amplia gama de versiones de Android desde API 15 hasta 22. https://possiblemobile.com/2013/06/context/#comment-2443283153
¡Porque no está garantizado que todas las operaciones descritas como soportadas por el Contexto de la Aplicación en la tabla siguiente funcionarán en todos los dispositivos Android!
- ¿Cuál es la manera más simple de invertir un ArrayList?
- Android: ¿Cómo crear un cuadro de diálogo sin título?