web-dev-qa-db-fra.com

Est-il prudent de sauvegarder le contexte de l'application dans une variable statique dans Android?

Je sais que l'utilisation de variables statiques sur Android est assez risquée, surtout si vous les référez à des activités. Cependant, si j'ai une classe qui étend Application (appelons cette classe "App"), est-il prudent de faire référence à l'instance de cette classe?

Si tel est le cas, est-il également sûr que toute autre classe ait une quelconque référence au contexte de l'application? Je veux dire, peut-il y avoir une fuite de mémoire si j'ai une référence au contexte de l'application dans n'importe quel type de classe?

Le but est que, quel que soit le domaine dans lequel je me trouve, je peux toujours obtenir une référence au contexte de l'application. Je pense que c'est sûr, car si le système ferme l'application, la variable statique disparaît également jusqu'au prochain démarrage de l'application, ce qui initialisera à nouveau la variable statique.

En outre, cela n'a pas beaucoup d'importance, mais si j'utilise plusieurs processus, aurai-je des références totalement différentes à la classe App sur chaque processus?

À titre d'exemple de code, voici ce à quoi je pense:

public class App extends Application
{
    private static Context _appContext;

    @Override
    public void onCreate()
    {
        super.onCreate();
        _appContext = this;
    }

    public static Context getAppContext()
    {
        return _appContext;
    }
}
43
android developer

est-il prudent de sauvegarder le contexte de l'application dans une variable statique?

Actuellement, oui, il semble être sûr, mais je n’aurais pas getAppContext() return Context, mais plutôt App ou Application.

Cela étant dit, le fait que l'équipe principale d'Android ne l'ait pas conçue de la sorte laisse penser qu'il existe peut-être des problèmes cachés dont nous n'avons pas connaissance, ou que cette approche pourrait à l'avenir poser des problèmes.

Comme l'acronyme de l'adage va, YMMV . :-)


EDIT

dans l'affirmative, est-il également sûr que toute autre classe ait une référence quelconque au contexte de l'application?

Je n'ai aucune idée de ce que vous entendez par "en sécurité" ici.

mais si j'utilise plusieurs processus, j'obtiendrai des références totalement différentes à App Class sur chaque processus, non?

Si vous utilisez plusieurs processus, vous devriez être giflé avec une truite. Mais, oui, vous devriez obtenir des instances distinctes App par processus.

28
CommonsWare

Cela devrait être sécuritaire. De plus, la note suivante de la documentation sur l'API pourrait vous intéresser:

Il n’est normalement pas nécessaire de sous-classe Application. Dans la plupart des cas, Des singletons statiques peuvent fournir les mêmes fonctionnalités de manière plus modulaire . Si votre singleton a besoin d'un contexte global (par exemple, pour enregistrer Récepteurs de diffusion), vous pouvez attribuer à la fonction de récupération un contexte Qui utilise en interne Context.getApplicationContext() lorsque A créé le singleton .

7
Dheeraj V.S.

Vous pouvez le faire en toute sécurité dans Application#onCreate() car la Application est créée avant toute activité. Si votre application est supprimée en arrière-plan, l'instance Application sera recréée et votre instance globale sera définie avant l'exécution de toute activité.

Il est important de noter que vous ne devez jamais définir de variables globales à partir d'une activité. Si vous le faites, votre application pourrait échouer de la manière suivante:

  1. Définir global dans l'activité A
  2. Naviguer vers l'activité B
  3. L'application passe en arrière-plan
  4. Framework tue application et processus
  5. L'application est restaurée
  6. Le framework crée l'activité B. Les activités dans le backstack ne sont pas créées tant que vous n'y retournez pas. Le global n'est donc pas défini!
  7. L'activité B tente d'utiliser global, et boum ... NullPointerException
4
Kevin Krumwiede

Un commentaire intéressant est apparu dans Studio lorsque je mettais de l'ordre dans des contextes statiques désagréables:

"Ceci est une fuite (et casse également Instant Run)."

Ainsi, avec le lancement d'Instant Run, nous avons le cas où les développeurs Android ne prévoient pas d'enregistrer des variables statiques. Bien que l'exécution instantanée ne soit pas (encore) à mon agenda, il est utile de savoir qu'il existe un exemple spécifique où ce n'est pas seulement une mauvaise pratique, mais le cas d'utilisation qui y est incorrect est identifié.

1
Ian Spencer

Ceci est l'avertissement lorsque vous créez un Context context; dans Android-studio:

Ne placez pas les classes de contexte Android dans des champs statiques; Il s’agit d’une fuite de mémoire qui interrompt également l’analyse instantanée. 

Un champ statique générera des fuites de contextes.

Les classes internes non statiques ont une référence implicite à leur classe externe . 

Si cette classe externe est par exemple un fragment ou une activité, cette référence Signifie que le gestionnaire/chargeur/tâche de longue durée contient une référence À l’activité qui l’empêche d’obtenir des déchets recueillis. De même, les références directes de champ aux activités et aux fragments De ces instances plus longues peuvent provoquer des fuites. 

Les classes ViewModel ne doivent jamais pointer sur des vues ou des contextes non applicatifs .

0
Ali Khaki