¿Hay alguna manera de obtener la Context
instancia actual dentro de un método estático?
Estoy buscando de esa manera porque odio guardar la instancia de 'Contexto' cada vez que cambia.
android
android-context
Andrea Baccega
fuente
fuente
Context
, entonces podría haber una mejor manera de diseñar el código.Respuestas:
Hacer esto:
En el archivo de manifiesto de Android, declare lo siguiente.
Luego escribe la clase:
Ahora llame
MyApplication.getAppContext()
a todas partes para obtener el contexto de su aplicación estáticamente.fuente
static context
variable comovolatile
?La mayoría de las aplicaciones que desean un método conveniente para obtener el contexto de la aplicación crean su propia clase que se extiende
android.app.Application
.GUÍA
Puede lograr esto creando primero una clase en su proyecto como la siguiente:
Luego, en su AndroidManifest, debe especificar el nombre de su clase en la etiqueta de AndroidManifest.xml:
Luego puede recuperar el contexto de la aplicación en cualquier método estático utilizando lo siguiente:
ADVERTENCIA
Antes de agregar algo como lo anterior a su proyecto, debe considerar lo que dice la documentación:
REFLEXIÓN
También hay otra forma de obtener el contexto de la aplicación utilizando la reflexión. La reflexión a menudo es menospreciada en Android y personalmente creo que esto no debería usarse en la producción.
Para recuperar el contexto de la aplicación, debemos invocar un método en una clase oculta ( ActivityThread ) que ha estado disponible desde la API 1:
Hay una clase oculta más ( AppGlobals ) que proporciona una forma de obtener el contexto de la aplicación de forma estática. Obtiene el contexto utilizando,
ActivityThread
por lo que realmente no hay diferencia entre el siguiente método y el publicado anteriormente:¡Feliz codificación!
fuente
Asumiendo que estamos hablando de obtener el Contexto de la Aplicación, lo implementé como lo sugirió @Rohit Ghatol extendiendo la Aplicación. Lo que sucedió entonces, es que no hay garantía de que el contexto recuperado de esa manera siempre sea no nulo. En el momento en que lo necesita, generalmente es porque desea inicializar un ayudante u obtener un recurso que no puede retrasar a tiempo; manejar el caso nulo no lo ayudará. Así que entendí que básicamente estaba luchando contra la arquitectura de Android, como se indica en los documentos
y explicado por Dianne Hackborn
Ella también sugiere la solución a este problema:
así que lo que hice fue deshacerme de extender la Aplicación y pasar el contexto directamente al getInstance () del ayudante singleton, mientras guardaba una referencia al contexto de la aplicación en el constructor privado:
la persona que llama luego pasará un contexto local al ayudante:
Por lo tanto, para responder esta pregunta correctamente: hay formas de acceder al contexto de la aplicación de forma estática, pero todos deben desalentarse, y debe preferir pasar un contexto local al getInstance () del singleton.
Para cualquier persona interesada, puede leer una versión más detallada en el blog de fwd
fuente
getInstance(ctx)
. Tiene una raízinstance
de tipo GCMyHelper
, que tiene un campomContext
de tipo privadoContext
, que hace referencia al contexto de la aplicación recopilada a través del contexto pasadogetInstance()
.instance
Nunca se establece una segunda vez, ni aclarado, por lo GC nunca coger el appcontext al que hace referenciainstance
. No pierde ninguna actividad, por lo que es un IMO de bajo costo.this
inApplication.onCreate()
, lo que mejora la respuesta aceptada.No, no creo que la haya. Desafortunadamente, estás atrapado llamando
getApplicationContext()
desdeActivity
o una de las otras subclases deContext
. Además, esta pregunta está algo relacionada.fuente
Aquí hay una forma no documentada de obtener una Aplicación (que es un Contexto) desde cualquier parte del hilo de la interfaz de usuario. Se basa en el método estático oculto
ActivityThread.currentApplication()
. Debería funcionar al menos en Android 4.x.Tenga en cuenta que es posible que este método devuelva nulo, por ejemplo, cuando llama al método fuera del hilo de la interfaz de usuario, o la aplicación no está vinculada al hilo.
Todavía es mejor usar la solución de @RohitGhatol si puede cambiar el código de la aplicación.
fuente
Depende de para qué esté utilizando el contexto. Puedo pensar en al menos una desventaja de ese método:
Si está intentando crear un
AlertDialog
conAlertDialog.Builder
, elApplication
contexto no funcionará. Creo que necesitas el contexto para el actualActivity
...fuente
Camino Kotlin :
Manifiesto:
MyApplication.kt
Luego puede acceder a la propiedad a través de
MyApplication.instance
fuente
Si está abierto a usar RoboGuice , puede inyectar el contexto en la clase que desee. Aquí hay una pequeña muestra de cómo hacerlo con RoboGuice 2.0 (beta 4 al momento de escribir esto)
fuente
He usado esto en algún momento:
Este es un contexto válido que utilicé para obtener servicios del sistema y funcionó.
Pero, lo usé solo en modificaciones de marco / base y no lo probé en aplicaciones de Android.
Una advertencia que debe saber: cuando se registre para recibir receptores de difusión con este contexto, no funcionará y obtendrá:
fuente
Kotlin
y obtener contexto como
o
fuente
Puedes usar lo siguiente:
MainActivity.java:
Cualquier otra clase:
fuente
Si no desea modificar el archivo de manifiesto, puede almacenar manualmente el contexto en una variable estática en su actividad inicial:
Y simplemente establezca el contexto cuando comience su actividad (o actividades):
Nota: Como todas las otras respuestas, esta es una pérdida potencial de memoria.
fuente
Creo que necesitas un cuerpo para el
getAppContext()
método:fuente
Según esta fuente , puede obtener su propio contexto extendiendo ContextWrapper
JavaDoc para ContextWrapper
fuente
Si por alguna razón desea el contexto de la Aplicación en cualquier clase, no solo en aquellas que extienden la aplicación / actividad, tal vez para algunas clases de fábrica o auxiliares. Puede agregar el siguiente singleton a su aplicación.
luego inicialícelo en onCreate de su clase de aplicación con
úsalo en cualquier lugar llamando
Sin embargo, no recomiendo este enfoque para nada más que el contexto de la aplicación. Como puede causar pérdidas de memoria.
fuente
Utilizo una variación del patrón de diseño Singleton para ayudarme con esto.
Luego llamo
ApplicationContextSingleton.setContext( this );
a mi actividad.onCreate () yApplicationContextSingleton.setContext( null );
en onDestroy () ;fuente
Acabo de lanzar un marco inspirado en jQuery para Android llamado Vapor API que tiene como objetivo simplificar el desarrollo de aplicaciones.
La
$
clase de fachada central mantiene unWeakReference
(enlace a una impresionante publicación de blog de Java sobre esto por Ethan Nicholas) en elActivity
contexto actual que puede recuperar llamando a:A
WeakReference
mantiene una referencia sin evitar que la recolección de basura recupere el objeto original, por lo que no debería tener problemas con las pérdidas de memoria.La desventaja, por supuesto, es que corre el riesgo de que
$.act()
pueda volver nulo. Sin embargo, aún no me he encontrado con este escenario, por lo que quizás sea solo un riesgo mínimo, vale la pena mencionar.También puede establecer el contexto manualmente si no lo está utilizando
VaporActivity
como suActivity
clase:Además, gran parte del marco de la API de Vapor usa este contexto almacenado inherentemente, lo que puede significar que no necesita almacenarlo usted mismo si decide usar el marco. Consulte el sitio para obtener más información y muestras.
Espero que eso ayude :)
fuente
La respuesta de Rohit parece correcta. Sin embargo, tenga en cuenta que "Instant Run" de AndroidStudio depende de no tener
static Context
atributos en su código, que yo sepa.fuente
en Kotlin, poner Contexto / Contexto de aplicación en objeto complementario todavía produce advertencia
Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
o si usas algo como esto:
Simplemente está engañando a la pelusa para no descubrir la pérdida de memoria, la instancia de la aplicación aún puede producir pérdida de memoria, ya que la clase de aplicación y su descendiente es un contexto.
Alternativamente, puede usar la interfaz funcional o las propiedades funcionales para ayudarlo a obtener el contexto de su aplicación.
Simplemente cree una clase de objeto:
o podría usarlo de manera más segura usando el tipo anulable:
y en tu clase de aplicación agrega esta línea:
y en tu manifiesto declara el nombre de la aplicación a
. MyApp
Cuando quieras obtener el contexto simplemente llama:
Espero que ayude.
fuente
Intenta algo como esto
fuente