Dans une application Android, y a-t-il un problème avec l'approche suivante:
public class MyApp extends android.app.Application {
private static MyApp instance;
public MyApp() {
instance = this;
}
public static Context getContext() {
return instance;
}
}
et le passer partout (par exemple SQLiteOpenHelper) où le contexte est requis (et non pas une fuite bien sûr)?
android
android-context
yanchenko
la source
la source
<application>
nœud de votre fichier AndroidManifest.xml pour inclure la définition d'attribut suivant:android:name="MyApp"
. MyApp doit se trouver sous le même package que vos références de manifeste.Réponses:
Il y a quelques problèmes potentiels avec cette approche, bien que dans de nombreuses circonstances (comme votre exemple), cela fonctionnera bien.
En particulier, vous devez être prudent lorsque vous traitez avec tout ce qui concerne le
GUI
qui nécessite unContext
. Par exemple, si vous passez le contexte d'application dans le,LayoutInflater
vous obtiendrez une exception. De manière générale, votre approche est excellente: c'est une bonne pratique d'utiliser unActivity's
Context
dedansActivity
, etApplication Context
quand vous passez un contexte au-delà de la portée d'unActivity
pour éviter les fuites de mémoire .En outre, comme alternative à votre modèle, vous pouvez utiliser le raccourci pour appeler
getApplicationContext()
unContext
objet (tel qu'une activité) pour obtenir le contexte d'application.la source
LayoutInflator
vient de fonctionner pour moi. Doit avoir été changé au cours des trois dernières années.D'après mon expérience, cette approche ne devrait pas être nécessaire. Si vous avez besoin du contexte pour quoi que ce soit, vous pouvez généralement l'obtenir via un appel à View.getContext () et en utilisant le
Context
obtenu, vous pouvez appeler Context.getApplicationContext () pour obtenir leApplication
contexte. Si vous essayez d'obtenir leApplication
contexte à partir d'un,Activity
vous pouvez toujours appeler Activity.getApplication () qui devrait pouvoir être transmis commeContext
nécessaire pour un appel àSQLiteOpenHelper()
.Dans l'ensemble, il ne semble pas y avoir de problème avec votre approche pour cette situation, mais lorsque vous traitez,
Context
assurez-vous de ne pas laisser fuir la mémoire, comme décrit sur le blog officiel des développeurs Android de Google .la source
Certaines personnes ont demandé: comment le singleton peut-il renvoyer un pointeur nul? Je réponds à cette question. (Je ne peux pas répondre dans un commentaire car j'ai besoin de poster du code.)
Il peut retourner null entre deux événements: (1) la classe est chargée et (2) l'objet de cette classe est créé. Voici un exemple:
Exécutons le code:
La deuxième ligne montre que Y.xinstance et X.yinstance sont nuls ; ils sont nuls car les variables X.xinstance et Y.yinstance ont été lues quand elles étaient nulles.
Cela peut-il être corrigé? Oui,
et ce code ne montre aucune anomalie:
MAIS ce n'est pas une option pour l'
Application
objet Android : le programmeur ne contrôle pas l'heure de sa création.Encore une fois: la différence entre le premier exemple et le second est que le deuxième exemple crée une instance si le pointeur statique est nul. Mais un programmeur ne peut pas créer l' objet d'application Android avant que le système ne décide de le faire.
MISE À JOUR
Un autre exemple déroutant où se trouvent des champs statiques initialisés
null
.Main.java :
Et vous obtenez:
Notez que vous ne pouvez pas déplacer la déclaration de variable statique d'une ligne vers le haut, le code ne sera pas compilé.
la source
Classe d'application:
Déclarez l'application dans AndroidManifest:
Usage:
la source
Vous essayez de créer un wrapper pour obtenir le contexte d'application et il est possible qu'il renvoie un
null
pointeur " ".Selon ma compréhension, je suppose que sa meilleure approche pour appeler l'un des 2
Context.getApplicationContext()
ouActivity.getApplication()
.la source
C'est une bonne approche. Je l'utilise moi aussi. Je suggérerais simplement de remplacer
onCreate
pour définir le singleton au lieu d'utiliser un constructeur.Et puisque vous avez mentionné
SQLiteOpenHelper
:onCreate ()
vous pouvez également ouvrir la base de données.Personnellement, je pense que la documentation s'est trompée en disant qu'il n'y a normalement pas besoin de sous-classer Application . Je pense que le contraire est vrai: vous devez toujours sous-classe Application.
la source
J'utiliserais le contexte d'application pour obtenir un service système dans le constructeur. Cela facilite les tests et bénéficie de la composition
La classe de test utiliserait alors le constructeur surchargé.
Android utiliserait le constructeur par défaut.
la source
J'aime ça, mais je suggérerais plutôt un singleton:
la source
new
appliquer l'application vous-même (à l'exception peut-être des tests unitaires). Le système d'exploitation le fera. Vous ne devez pas non plus avoir de constructeur. C'est pour çaonCreate
.J'utilise la même approche, je suggère d'écrire un peu mieux le singleton:
mais je n'utilise pas partout, j'utilise
getContext()
etgetApplicationContext()
où je peux le faire!la source