Cycle de vie des objets statiques Android

101

Je crée une application de recherche d'événement, nous définissons des critères de recherche à partir d'un écran, remplissons un autre écran, puis l'utilisateur peut modifier les critères de recherche à partir du 3ème écran et passe au 4ème écran.

Pour accomplir la tâche ci-dessus, j'utilise un objet statique qui se souvient des valeurs autour de l'application et je n'ai rien de plus à faire.

Mais j'ai peur si sur le cycle de vie des objets statiques dans Android, si la mémoire est faible, Android supprime les objets statiques ???

Comme Android prend en charge le multitâche, si l'utilisateur passe à une autre application et lorsque l'utilisateur revient, l'application commence à agir de manière folle, l'objet statique est-il supprimé lorsqu'il effectue plusieurs tâches ??? une idée ?? et suggèrent également de maintenir un objet statique via la méthode singleton est une meilleure approche ???

d-man
la source

Réponses:

239

Commençons par un peu de contexte: que se passe-t-il lorsque vous démarrez une application?
Le système d'exploitation démarre un processus et lui attribue un identifiant de processus unique et alloue une table de processus. Un processus démarre une instance de DVM (Dalvik VM); Chaque application s'exécute dans un DVM.
Un DVM gère le déchargement de chargement de classe, le cycle de vie de l'instance, le GC, etc.

Durée de vie d'une variable statique: une variable statique prend naissance lorsqu'une classe est chargée par la JVM et meurt lorsque la classe est déchargée.

Donc, si vous créez une application Android et initialisez une variable statique, elle restera dans la JVM jusqu'à ce que l'un des événements suivants se produise:
1. la classe est déchargée
2. la JVM s'arrête
3. le processus meurt

Notez que la valeur de la variable statique persistera lorsque vous basculerez vers une autre activité d'une autre application et qu'aucune des trois activités ci-dessus ne se produit. Si l'un des trois ci-dessus se produit, la valeur statique perdra sa valeur.

Vous pouvez tester cela avec quelques lignes de code:

  1. imprimer la statique non initialisée dans onCreate de votre activité -> devrait afficher null
  2. initialisez le statique. imprimer -> la valeur serait non nulle
  3. Appuyez sur le bouton de retour et allez à l'écran d'accueil. Remarque: l'écran d'accueil est une autre activité.
  4. Relancez votre activité -> la variable statique sera non nulle
  5. Tuez votre processus d'application à partir de DDMS (bouton d'arrêt dans la fenêtre des appareils).
  6. Redémarrez votre activité -> la statique aura une valeur nulle.

J'espère que cela pourra aider.

Samuh
la source
1
Je veux savoir pourquoi je perds ma valeur de champ dans l'objet d'application si elle n'est pas statique lorsque je démarre une nouvelle activité par exemple je déclare la page courante variable dans l'objet d'application et sa valeur revient toujours à zéro lorsque j'ouvre une nouvelle activité
Mohammed Subhi Sheikh Quroush
quand j'appelle super.onRestoreInstanceState (savedInstanceState); Je perds ma variable même si elles sont statiques, quel est le problème?
Mohammed Subhi Sheikh Quroush
1
c'est une belle explication (donc pas de -1) mais c'est un peu sans importance: l'OP a demandé explicitement des "situations de mémoire faible" (même raison pour laquelle je suis ici), où pour autant que je sache, les Os pourraient tuer la VM et redémarrez-le plus tard avec les mêmes paramètres, et ce cas ( SI c'est une chose réelle) n'est pas couvert ici ...
Rick77
1
@suitianshi Je pense que nous pouvons initialiser des instances statiques dans Application.onCreate, car même si notre application passe en arrière-plan et que le processus est tué, dès que nous retournons à notre application, la classe Application sera instanciée et appellera ses méthodes de cycle de vie correspondantes encore! bien que j'aie besoin de confirmation à ce sujet, je me demande s'il pourrait y avoir un scénario où l'instance statique initialisée dans Application.onCreate perd sa valeur?
Sarthak Mittal
1
Ce qui me manque ici, c'est une explication pour "1. la classe est déchargée" - quand cela se passerait-il? La JVM déchargerait-elle une classe si elle manque de mémoire?
stoefln
16

Eh bien, le modèle Singleton est également basé sur l'utilisation de variables statiques, donc vous seriez dans la même position. Bien que l'approche statique puisse fonctionner la plupart du temps, il peut arriver que dans certains cas, lorsque la mémoire est pleine et qu'une autre activité passe au premier plan avant que votre application ne passe à son écran suivant, le processus de votre activité puisse être interrompu et vous perdez les valeurs statiques. Cependant, Android propose quelques options de valeurs persistantes entre les états ou de les transmettre telles que:

  • en utilisant une intention, vous pouvez transmettre vos critères de recherche d'une activité à l'autre (similaire à une requête http Web)
  • en utilisant les préférences de l'application, vous pouvez enregistrer les valeurs et les récupérer dans l'activité qui en a besoin
  • en utilisant la base de données sqlite, vous pouvez les conserver dans une table et les récupérer plus tard
  • si vous devez simplement enregistrer l'état d'activité afin qu'au redémarrage, les champs soient remplis avec leurs valeurs précédemment sélectionnées, vous pouvez implémenter la méthode d'activité onSaveInstanceState () - notez que cela n'est pas recommandé pour la persistance des états entre les activités.

Vous pouvez obtenir des exemples de code de l'utilisation des préférences, des intentions et de la base de données sqlite en consultant l' arborescence du code source aegis-shield dans le code google ou dans d'autres applications Android open source.

r1k0
la source
6

Après quelques recherches, il s'avère que l'utilisation d'Application pour stocker des singletons n'est pas une bonne idée, à moins que vous ne soyez prêt à la recréer:

Ne stockez pas de données dans l'objet d'application

ainsi, bien que la réponse acceptée soit techniquement correcte, elle ne fournit pas toutes les informations.

Comme le lien ci-dessus le suggère, si vous voulez vraiment vous en tenir à ce modèle, vous devez être prêt à vérifier la valeur nulle et à recréer les données, si possible.

Rick77
la source
3

@ r1k0 est ici. Le stockage des données dans les champs statiques d'une classe ne persistera pas de lui-même pendant les arrêts et redémarrages du processus d'application. Android tue régulièrement les processus (exécutant des applications) lorsqu'il a besoin de mémoire.

Selon la doc Android: état d'activité et éjection de la mémoire ,

Le système ne tue jamais directement une activité. Au lieu de cela, il tue le processus dans lequel l'activité s'exécute, détruisant non seulement l'activité mais également tout le reste en cours d'exécution dans le processus.

Vous pouvez enregistrer et restaurer l'état des primitives ainsi que des objets sérialisables et parcellables à l'aide des méthodes ci-dessous. Ceux-ci sont automatiquement appelés pendant le cycle de vie normal de l'activité.

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

Donc, si vous avez une classe qui n'a que des variables statiques, vous pouvez enregistrer l'état de chaque champ dans onSaveInstanceState () et les restaurer dans onRestoreInstanceState (). Lorsque Android arrête le processus dans lequel votre application s'exécute, l'état de vos variables sera enregistré et, lorsque Android restaure votre application, les valeurs seront restaurées en mémoire dans le même état qu'auparavant.

eric.mcgregor
la source