Android détruisant des activités, tuant des processus

117

Salut, je me demande comment Android gère la mémoire et je ne trouve nulle part de réponse précise. Supposons que j'ai une application avec 5 activités sur la pile d'activité actuelle (4 sont arrêtées et 1 est reprise), il n'y a pas de service connecté. J'appuie sur le bouton HOME pour que toutes mes activités soient arrêtées. Je lance une autre application consommatrice de mémoire et la mémoire globale de l'appareil commence à être faible. Et la question est

... Qu'arrivera-t-il à ma candidature?

  1. Le système peut-il détruire une ou certaines de mes activités pour récupérer de la mémoire?
  2. Le système va-t-il tuer tout le processus de mon application? Toutes les activités seront-elles bien détruites?
  3. Que se passera-t-il lorsque je reviendrai à mon application lorsqu'elle a été totalement supprimée? Va-t-il commencer à partir du début (comme le premier démarrage) ou va-t-il essayer de récupérer les activités à l'état précédent / si oui - est-ce seulement celle qui se trouve en haut de la pile ou toutes?

METTRE À JOUR:

Avant de poser cette question, j'ai vu le cycle de vie de l'activité à plusieurs reprises, mais il n'a pas de réponses à mes questions. J'ai fait quelques tests et j'ai quelques réponses. «Arrêter le processus» dans DDMS était un indice pour les tests.

Je n'ai pas testé la réponse à la question 1, mais comme le guide le dit:

Si une activité est mise en pause ou arrêtée, le système peut supprimer l'activité de la mémoire en lui demandant de terminer ou simplement en tuant son processus.

Il semble qu'une ou plusieurs des activités peuvent être détruites doucement (avec la méthode onDestroy) sans tuer le processus. Vous obtiendrez simplement (onCreate + bundle) lorsque vous y reviendrez.

Réponse à la question 2:

OUI. En général, le système tue l'ensemble du processus, cela signifie que toutes les données, y compris les activités et les champs statiques, sont détruites. Ce n'est PAS fait correctement - vous n'obtiendrez pas onDestroy ou finialize () pour aucune de vos activités interrompues / arrêtées. C'est pourquoi saveInstanceState () est appelée juste avant la méthode onPause. onPause est fondamentalement la dernière méthode où vous devriez enregistrer quelque chose car après cette méthode, vous ne pourriez jamais voir onStop ou onDestroy. Le système peut simplement tuer le processus en détruisant tous vos objets quoi qu'ils contiennent et quoi qu'ils fassent.

Réponse à la question 3:

Que se passe-t-il lorsque vous revenez à une application supprimée?

  • Avant Android 2.2 - l'application démarrera dès le début, avec l'activité du lanceur.
  • À partir de la version 2.2, le système restaurera l'état précédent de l'application. Qu'est-ce que ça veut dire? Cela signifie que la dernière activité visible sera recréée (onCreate + bundle). Que se passera-t-il avec la pile d'activités? La pile est bonne mais toutes les activités dessus sont mortes. Chacun d'entre eux sera recréé (onCreate + bundle) lorsque vous y reviendrez avec le bouton retour. Il y a encore une chose à ce sujet:

Normalement, le système efface une tâche (supprime toutes les activités de la pile au-dessus de l'activité racine) dans certaines situations lorsque l'utilisateur sélectionne à nouveau cette tâche à partir de l'écran d'accueil. En règle générale, cela est fait si l'utilisateur n'a pas visité la tâche pendant un certain temps, par exemple 30 minutes.

Conclusion?

  1. Ne pensez pas que la gestion des problèmes de rotation des activités peut être résolue par android: configChanges = "orientation". Lorsque vous faites cela, vous aurez de nombreux autres problèmes dont vous n'êtes même pas au courant.
  2. Testez votre application avec DDMS - bouton Arrêter le processus. Regarde ça
  3. Soyez prudent lorsque vous utilisez des variables statiques. Ne pensez pas que lorsque vous les initialiserez dans l'activité 1 - vous les aurez initialisés dans l'activité 2. Le seul endroit sûr pour initialiser la statique globale serait la classe Application.
  4. N'oubliez pas que vous ne verrez peut-être jamais onStop ou onDestroy. Fermez les fichiers / bases de données, arrêtez les téléchargeurs dans onPause. Lorsque vous voulez que l'application fasse quelque chose dans BG - utilisez le service de premier plan.

Ce serait ça ... J'espère que j'ai aidé avec mon essey :)

marque
la source
Pour votre hypothèse, ces 5 activités proviennent-elles d'une même application ou de plusieurs applications différentes?
dumbfingers
1
"J'ai une application avec 5 activités sur la pile d'activités en cours" Bien sûr, elles proviennent toutes de ma, une, même application de processus.
Mark
4
Merci, c'était exactement ma question aussi ... Votre question et les réponses m'ont beaucoup aidé.
craigrs84
@Mark: Ce problème est-il résolu maintenant? Et si c'est le cas?
Ameer Moaaviah

Réponses:

30

Jetez d'abord un œil à ceci:

img1

onPause () Appelé lorsque le système est sur le point de reprendre une activité précédente. Ceci est généralement utilisé pour valider des modifications non enregistrées sur des données persistantes, arrêter des animations et d'autres choses qui peuvent consommer du processeur, etc. Les implémentations de cette méthode doivent être très rapides car l'activité suivante ne sera pas reprise tant que cette méthode ne sera pas retournée. Suivi par onResume () si l'activité revient au premier plan, ou par onStop () si elle devient invisible pour l'utilisateur.

onStop () Appelé lorsque l'activité n'est plus visible pour l'utilisateur, car une autre activité a été reprise et couvre celle-ci. Cela peut se produire soit parce qu'une nouvelle activité est en cours de démarrage, une activité existante est amenée devant celle-ci, soit celle-ci est en cours de destruction. Suivi soit par onRestart () si cette activité revient pour interagir avec l'utilisateur, soit par onDestroy () si cette activité disparaît.

Ainsi, lorsque vous appuyez sur le bouton « HOME » sur votre appareil, votre activité de premier plan en cours est mis sur onPause()puis onStop(), l'autre 4 devrait resteronStop()

Selon les documents de Google:

  • Si une activité au premier plan de l'écran (en haut de la pile), elle est active ou en cours d'exécution.
  • Si une activité a perdu le focus mais est toujours visible (c'est-à-dire qu'une nouvelle activité non pleine taille ou transparente a le focus sur votre activité), elle est mise en pause. Une activité suspendue est complètement active (elle conserve toutes les informations d'état et de membre et reste attachée au gestionnaire de fenêtres), mais peut être supprimée par le système dans des situations de mémoire extrêmement faible.
  • Si une activité est complètement masquée par une autre activité, elle est arrêtée. Il conserve toujours toutes les informations d'état et de membre, cependant, il n'est plus visible pour l'utilisateur, sa fenêtre est donc masquée et elle sera souvent supprimée par le système lorsque de la mémoire est nécessaire ailleurs.
  • Si une activité est mise en pause ou arrêtée, le système peut supprimer l'activité de la mémoire en lui demandant de terminer ou simplement en tuant son processus. Lorsqu'il est à nouveau affiché à l'utilisateur, il doit être complètement redémarré et restauré à son état antérieur.

Et, pour le cycle de vie des processus:

Cycle de vie du processus 3. Une activité d'arrière-plan (une activité qui n'est pas visible par l'utilisateur et qui a été suspendue) n'est plus critique, de sorte que le système peut arrêter en toute sécurité son processus pour récupérer de la mémoire pour d'autres processus visibles ou de premier plan. Si son processus doit être tué, lorsque l'utilisateur retourne à l'activité (la rendant à nouveau visible à l'écran), sa méthode onCreate (Bundle) sera appelée avec le savedInstanceState qu'il avait précédemment fourni dans onSaveInstanceState (Bundle) afin qu'il peut se redémarrer dans le même état que l'utilisateur l'a quitté en dernier.

Toutes les citations ci-dessus proviennent de: Référence des développeurs Android: Activité

Il est confirmé que le système peut détruire les activités non actives et recycler les mémoires lorsque vous lancez certaines applications consommatrices de mémoire. Et vous pouvez implémenter comme: isFinishing()dans votre activité, puis en utilisant le bouton "tuer" dans DDMS pour détecter laquelle de vos activités est abandonnée par le système. Mais je suppose que le système détruira d'abord le plus ancien. Cependant, il ne sert à rien de conserver d'autres activités lorsque l '«activité de lancement» a été recyclée.

METTRE À JOUR

Voici quelques opinions que j'ai trouvées d' ici :

État arrêté

Lorsqu'une activité n'est pas visible, mais toujours en mémoire, on dit qu'elle est à l'état arrêté. L'activité arrêtée peut être ramenée à l'avant pour redevenir une activité de course à pied. Ou, il pourrait être détruit et supprimé de la mémoire.

Le système maintient les activités dans un état arrêté car il est probable que l'utilisateur voudra toujours revenir bientôt à ces activités, et redémarrer une activité arrêtée est beaucoup moins cher que de démarrer une activité à partir de zéro. C'est parce que nous avons déjà tous les objets chargés en mémoire et que nous devons simplement tout mettre au premier plan.

Les activités arrêtées peuvent être supprimées de la mémoire à tout moment.

haltères
la source
4
La documentation est assez déroutante sur cette question, cependant seul un processus entier peut être tué, pas des composants individuels (activités, services, etc.). Voir: stackoverflow.com/questions/7536988/…
greg7gkb
Cette question devrait être mise à jour avec les informations dans le lien de @ greg7gkb commentaire, c'est trompeur
Luke De Feo
1

Le système peut-il détruire une ou certaines de mes activités pour récupérer de la mémoire?

Oui. Android tue les activités qui s'exécutent en arrière-plan lorsqu'il y a un besoin de mémoire. Tuer un ou tous peut dépendre de certaines conditions. Pour une instance mise en pause ou arrêtée, Android peut tuer une activité ou un processus lui-même. Ici, sous Cycle de vie des activités, vous pouvez obtenir les points ci-dessous. Je vous recommande de parcourir cette page complètement. Cela effacera certainement vos doutes.

Si une activité a perdu le focus mais est toujours visible (c'est-à-dire qu'une nouvelle activité non pleine taille ou transparente a le focus sur votre activité), elle est mise en pause. Une activité suspendue est complètement active (elle conserve toutes les informations d'état et de membre et reste attachée au gestionnaire de fenêtres), mais peut être supprimée par le système dans des situations de mémoire extrêmement faible.

Si une activité est complètement masquée par une autre activité, elle est arrêtée. Il conserve toujours toutes les informations d'état et de membre, cependant, il n'est plus visible pour l'utilisateur, sa fenêtre est donc masquée et elle sera souvent supprimée par le système lorsque de la mémoire est nécessaire ailleurs.

Si une activité est mise en pause ou arrêtée, le système peut supprimer l'activité de la mémoire en lui demandant de terminer ou simplement en tuant son processus. Lorsqu'il est à nouveau affiché à l'utilisateur, il doit être complètement redémarré et restauré à son état antérieur.


Le système va-t-il tuer tout le processus de mon application? Toutes les activités seront-elles bien détruites?

L'activité se rapporte à un individu tandis que le processus se rapporte à un groupe d'activités. Regardez à nouveau le troisième point ci-dessus, il tue le processus comme mentionné.


Que se passera-t-il lorsque je reviendrai à mon application lorsqu'elle a été totalement supprimée?

C'est similaire à redémarrer. Encore une fois, le troisième point vous donnera des réponses commeWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Obtenez plus d'informations sur les éléments liés à la mémoire ici .

Modifier:
toutes les activités d'une application s'exécutent en un seul processus. Ainsi, lorsqu'un processus est tué, toutes les activités, peu importe 5 ou 10, seront tuées, c'est-à-dire redémarrées. Le redémarrage fera démarrer votre application à partir d'un début sans état enregistré.

Vinay
la source
2
J'ai vu Activity Lifecycle au moins 5 fois mais cela ne répond pas à mes questions. Ce que vous avez dit signifierait lorsque mon processus d'application est tué - lorsque je reviens à l'application, il est restauré à son état précédent. Donc, quand j'ai eu 5 activités arrêtées ... est-ce qu'elles sont toutes mortes (invoqué onDestroy) quand le processus a été tué? Lorsque je suis revenu sur mon application, toutes les activités ont-elles été restaurées (onCreate + bundle) ou uniquement celle située en haut de la pile (visible par l'utilisateur)?
Mark
1
Toutes les activités d'une application s'exécutent en un seul processus. Ainsi, lorsqu'un processus est tué, toutes les activités, peu importe 5 ou 10, seront tuées, c'est-à-dire redémarrées. Le redémarrage entraînera le démarrage de votre application à partir d'un début, aucun état enregistré.
Vinay
1
Presque vrai, mais pas pour 2.2 et plus. Voir ma MISE À JOUR en haut de la page.
Mark
1
Non, ce n'est pas vrai et cela n'a jamais été vrai. C'est déroutant basé sur la documentation, mais voir: stackoverflow.com/questions/7536988/…
greg7gkb
2
@JJPA Android ne peut pas détruire des activités uniques pour récupérer de la mémoire, il ne détruit que des processus. Voir cette réponse de Dianne Hackbor, membre de l'équipe principale d'Android impliquée dans l'implémentation "out of memory killer": stackoverflow.com/a/7576275/1290264 .
bcorso