En una aplicación de Android, ¿hay algún problema con el siguiente enfoque:
public class MyApp extends android.app.Application {
private static MyApp instance;
public MyApp() {
instance = this;
}
public static Context getContext() {
return instance;
}
}
y pasarlo a todas partes (por ejemplo, SQLiteOpenHelper) donde se requiere contexto (y no se filtra, por supuesto)?
android
android-context
Yanchenko
fuente
fuente
<application>
nodo del archivo AndroidManifest.xml incluir la siguiente definición de atributo:android:name="MyApp"
. MyApp debe estar bajo el mismo paquete que sus referencias de manifiesto.Respuestas:
Hay un par de problemas potenciales con este enfoque, aunque en muchas circunstancias (como su ejemplo) funcionará bien.
En particular, debe tener cuidado al tratar con cualquier cosa que se ocupe de lo
GUI
que requiere aContext
. Por ejemplo, si pasa el contexto de la aplicaciónLayoutInflater
, obtendrá una excepción. En términos generales, su enfoque es excelente: es una buena práctica usar unActivity's
Context
dentro de esoActivity
yApplication Context
al pasar un contexto más allá del alcance de unActivity
para evitar pérdidas de memoria .Además, como alternativa a su patrón, puede usar el atajo de invocar
getApplicationContext()
unContext
objeto (como una Actividad) para obtener el Contexto de la aplicación.fuente
LayoutInflator
simplemente funcionó para mí. Debe haber sido cambiado en los últimos tres años.En mi experiencia, este enfoque no debería ser necesario. Si necesita el contexto para cualquier cosa, generalmente puede obtenerlo mediante una llamada a View.getContext () y utilizando el
Context
obtenido allí puede llamar a Context.getApplicationContext () para obtener elApplication
contexto. Si está tratando de obtener elApplication
contexto de estoActivity
, siempre puede llamar a Activity.getApplication (), que debería poder pasarse segúnContext
sea necesario para una llamadaSQLiteOpenHelper()
.En general, no parece haber un problema con su enfoque para esta situación, pero al tratar,
Context
asegúrese de no perder memoria en ninguna parte, como se describe en el blog oficial de Google Android Developers .fuente
Algunas personas han preguntado: ¿cómo puede el singleton devolver un puntero nulo? Estoy respondiendo esa pregunta. (No puedo responder en un comentario porque necesito publicar el código).
Puede devolver nulo entre dos eventos: (1) se carga la clase y (2) se crea el objeto de esta clase. Aquí hay un ejemplo:
Ejecutemos el código:
La segunda línea muestra que Y.xinstance y X.yinstance son nulos ; son nulos porque las variables X.xinstance y Y.yinstance se leyeron cuando eran nulas.
¿Se puede arreglar esto? Si,
y este código no muestra anomalía:
PERO esto no es una opción para el
Application
objeto Android : el programador no controla el momento en que se crea.Una vez más: la diferencia entre el primer ejemplo y el segundo es que el segundo ejemplo crea una instancia si el puntero estático es nulo. Pero un programador no puede crear el objeto de la aplicación de Android antes de que el sistema decida hacerlo.
ACTUALIZAR
Un ejemplo más desconcertante donde los campos estáticos inicializados resultan ser
null
.Main.java :
Y obtienes:
Tenga en cuenta que no puede mover la declaración de variable estática una línea hacia arriba, el código no se compilará.
fuente
Clase de aplicación:
Declare la aplicación en el AndroidManifest:
Uso:
fuente
Está intentando crear un contenedor para obtener el Contexto de la aplicación y existe la posibilidad de que devuelva el "
null
" puntero.Según tengo entendido, supongo que es un mejor enfoque para llamar a cualquiera de los 2
Context.getApplicationContext()
oActivity.getApplication()
.fuente
Es un buen enfoque. Yo también lo uso. Solo sugeriría anular
onCreate
para establecer el singleton en lugar de usar un constructor.Y como mencionaste
SQLiteOpenHelper
:onCreate ()
también puedes abrir la base de datos.Personalmente, creo que la documentación se equivocó al decir que normalmente no hay necesidad de subclasificar Aplicación . Creo que lo contrario es cierto: siempre debe subclasificar Aplicación.
fuente
Usaría el contexto de aplicación para obtener un servicio del sistema en el constructor. Esto facilita las pruebas y los beneficios de la composición.
La clase de prueba usaría el constructor sobrecargado.
Android usaría el constructor predeterminado.
fuente
Me gusta, pero sugeriría un singleton en su lugar:
fuente
new
la Aplicación usted mismo (con la posible excepción de las pruebas unitarias). El sistema operativo lo hará. Tampoco deberías tener un constructor. Para eso es esoonCreate
.Estoy usando el mismo enfoque, sugiero escribir el singleton un poco mejor:
¡pero no lo estoy usando en todas partes, lo uso
getContext()
ygetApplicationContext()
donde puedo hacerlo!fuente