Existe-t-il un moyen d'obtenir l' Context
instance actuelle dans une méthode statique?
Je cherche de cette façon parce que je déteste enregistrer l'instance "Context" à chaque fois qu'elle change.
android
android-context
Andrea Baccega
la source
la source
Context
, alors il pourrait y avoir un meilleur moyen de concevoir le code.Réponses:
Faites ceci:
Dans le fichier manifeste Android, déclarez ce qui suit.
Écrivez ensuite la classe:
Maintenant, appelez partout
MyApplication.getAppContext()
pour obtenir le contexte de votre application de manière statique.la source
static context
variable commevolatile
?La majorité des applications qui souhaitent une méthode pratique pour obtenir le contexte d'application créent leur propre classe qui s'étend
android.app.Application
.GUIDER
Vous pouvez accomplir cela en créant d'abord une classe dans votre projet comme suit:
Ensuite, dans votre AndroidManifest, vous devez spécifier le nom de votre classe dans la balise AndroidManifest.xml:
Vous pouvez ensuite récupérer le contexte d'application dans n'importe quelle méthode statique à l'aide de ce qui suit:
ATTENTION
Avant d'ajouter quelque chose comme ce qui précède à votre projet, vous devez considérer ce que dit la documentation:
RÉFLEXION
Il existe également une autre façon d'obtenir le contexte de l'application à l'aide de la réflexion. La réflexion est souvent méprisée dans Android et je pense personnellement que cela ne devrait pas être utilisé en production.
Pour récupérer le contexte de l'application, nous devons appeler une méthode sur une classe cachée ( ActivityThread ) qui est disponible depuis l'API 1:
Il existe une autre classe cachée ( AppGlobals ) qui fournit un moyen d'obtenir le contexte d'application de manière statique. Il obtient le contexte en utilisant
ActivityThread
donc il n'y a vraiment aucune différence entre la méthode suivante et celle publiée ci-dessus:Bon codage!
la source
En supposant que nous parlons d'obtenir le contexte d'application, je l'ai implémenté comme suggéré par @Rohit Ghatol étendant l'application. Ce qui s'est passé alors, c'est qu'il n'y a aucune garantie que le contexte récupéré de cette manière sera toujours non nul. Au moment où vous en avez besoin, c'est généralement parce que vous voulez initialiser un assistant, ou obtenir une ressource, que vous ne pouvez pas retarder dans le temps; la gestion du cas nul ne vous aidera pas. J'ai donc compris que je me battais essentiellement contre l'architecture Android, comme indiqué dans la documentation
et expliqué par Dianne Hackborn
Elle propose également la solution à ce problème:
donc ce que j'ai fait était de me débarrasser de l'extension d'Application et de passer le contexte directement à getInstance () de l'assistant singleton, tout en enregistrant une référence au contexte d'application dans le constructeur privé:
l'appelant transmettra ensuite un contexte local à l'assistant:
Donc, pour répondre correctement à cette question: il existe des moyens d'accéder statiquement au contexte d'application, mais ils doivent tous être découragés, et vous devriez préférer passer un contexte local à getInstance () du singleton.
Pour toute personne intéressée, vous pouvez lire une version plus détaillée sur le blog fwd
la source
getInstance(ctx)
. Vous avez une racine GCinstance
de typeMyHelper
, qui possède un champ privémContext
de typeContext
, qui fait référence au contexte d'application collecté via le contexte transmis àgetInstance()
.instance
n'est jamais défini une deuxième fois, ni effacé, donc GC n'attrapera jamais le contexte d'application référencé parinstance
. Vous ne fuyez aucune activité, c'est donc l'OMI à faible coût.this
inApplication.onCreate()
, ce qui améliore la réponse acceptée.Non, je ne pense pas. Malheureusement, vous êtes bloqué
getApplicationContext()
depuisActivity
ou l'une des autres sous-classes deContext
. En outre, cette question est quelque peu liée.la source
Voici une façon non documentée d'obtenir une application (qui est un contexte) de n'importe où dans le thread d'interface utilisateur. Il repose sur la méthode statique cachée
ActivityThread.currentApplication()
. Cela devrait fonctionner au moins sur Android 4.x.Notez qu'il est possible que cette méthode retourne null, par exemple lorsque vous appelez la méthode en dehors du thread d'interface utilisateur, ou que l'application n'est pas liée au thread.
Il est toujours préférable d'utiliser la solution de @RohitGhatol si vous pouvez changer le code d'application.
la source
Cela dépend de ce pour quoi vous utilisez le contexte. Je peux penser à au moins un inconvénient de cette méthode:
Si vous essayez de créer un
AlertDialog
avecAlertDialog.Builder
, leApplication
contexte ne fonctionnera pas. Je crois que vous avez besoin du contexte du courantActivity
...la source
Façon Kotlin :
Manifeste:
MyApplication.kt
Vous pouvez ensuite accéder à la propriété via
MyApplication.instance
la source
Si vous êtes prêt à utiliser RoboGuice , vous pouvez injecter le contexte dans la classe de votre choix . Voici un petit échantillon de la façon de le faire avec RoboGuice 2.0 (beta 4 au moment de la rédaction de cet article)
la source
Je l'ai utilisé à un moment donné:
C'est un contexte valide que j'ai utilisé pour obtenir des services système et travailler.
Mais, je ne l'ai utilisé que dans les modifications de framework / base et je ne l'ai pas essayé dans les applications Android.
Un avertissement que vous devez savoir: lors de votre inscription à des récepteurs de diffusion dans ce contexte, cela ne fonctionnera pas et vous obtiendrez:
la source
Kotlin
et obtenez le contexte comme
ou
la source
Vous pouvez utiliser les éléments suivants:
MainActivity.java:
Toute autre classe:
la source
Si vous ne souhaitez pas modifier le fichier manifeste, vous pouvez stocker manuellement le contexte dans une variable statique dans votre activité initiale:
Et définissez simplement le contexte lorsque votre activité (ou vos activités) commence:
Remarque: comme toutes les autres réponses, il s'agit d'une fuite de mémoire potentielle.
la source
Je pense que vous avez besoin d'un corps pour la
getAppContext()
méthode:la source
Selon cette source, vous pouvez obtenir votre propre contexte en étendant ContextWrapper
JavaDoc pour ContextWrapper
la source
Si, pour une raison quelconque, vous voulez le contexte d'application dans n'importe quelle classe, pas seulement ceux qui étendent l'application / l'activité, peut-être pour certaines classes d'usine ou d'assistance. Vous pouvez ajouter le singleton suivant à votre application.
puis l'initialiser dans onCreate de votre classe d'application avec
utilisez-le n'importe où en appelant
Je ne recommande cependant pas cette approche à autre chose qu'au contexte d'application. Comme cela peut provoquer des fuites de mémoire.
la source
J'utilise une variation du modèle de conception Singleton pour m'aider avec cela.
Je demande alors
ApplicationContextSingleton.setContext( this );
à mon activity.onCreate () etApplicationContextSingleton.setContext( null );
dans OnDestroy () ;la source
Je viens de publier un framework inspiré de jQuery pour Android appelé Vapor API qui vise à simplifier le développement d'applications.
La
$
classe de façade centrale maintient unWeakReference
(lien vers un impressionnant article de blog Java à ce sujet par Ethan Nicholas) sur leActivity
contexte actuel que vous pouvez récupérer en appelant:A
WeakReference
conserve une référence sans empêcher la récupération de place de récupérer l'objet d'origine, vous ne devriez donc pas avoir de problème avec les fuites de mémoire.L'inconvénient est bien sûr que vous courez le risque qui
$.act()
pourrait retourner nul. Je n'ai pas encore rencontré ce scénario, donc c'est peut-être juste un risque minimal, qui mérite d'être mentionné.Vous pouvez également définir le contexte manuellement si vous n'utilisez pas
VaporActivity
votreActivity
classe:En outre, une grande partie du cadre de l' API Vapor utilise ce contexte stocké de manière inhérente, ce qui pourrait signifier que vous n'avez pas besoin de le stocker vous-même du tout si vous décidez d'utiliser le cadre. Consultez le site pour plus d'informations et d'échantillons.
J'espère que ça aide :)
la source
La réponse de Rohit semble correcte. Cependant, sachez que "Instant Run" d'AndroidStudio dépend de ne pas avoir d'
static Context
attributs dans votre code, pour autant que je sache.la source
dans Kotlin, mettre Context / App Context dans un objet compagnon produit toujours un avertissement
Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
ou si vous utilisez quelque chose comme ça:
C'est simplement duper les peluches pour ne pas découvrir la fuite de mémoire, l'instance App peut toujours produire une fuite de mémoire, car la classe Application et son descendant est un contexte.
Vous pouvez également utiliser une interface fonctionnelle ou des propriétés fonctionnelles pour vous aider à obtenir le contexte de votre application.
Créez simplement une classe d'objets:
ou vous pouvez l'utiliser plus en toute sécurité en utilisant le type nullable:
et dans votre classe App, ajoutez cette ligne:
et dans votre manifeste, déclarez le nom de l'application
. MyApp
Lorsque vous voulez obtenir le contexte, appelez simplement:
J'espère que cela vous aidera.
la source
Essayez quelque chose comme ça
la source