gestion de la mémoire android dans le cycle de vie des activités
Ma question est un peu compliquée.
je veux comprendre comment l'application traite les ressources (en particulier les images pour les fonds, les boutons, etc.) lorsque L'activité est commencée, puis suspendue.
par exemple, je commence L'activité A, elle montre toutes les images sur l'écran, mange sa mémoire, puis une autre activité B est lancée et A est suspendue. Qu'advient-il de toutes les images, les ressources, etc.? Quand ils sont libérés? Comment puis-je prendre le contrôle d'eux? Ne devrais-je pas garder L'activité A dans la mémoire et l'enlever de la pile D'activités?
Si vous avez besoin d'éclaircissements pour mes questions, pls m'écrire!
Merci d'avance! Danail
5 réponses
L'activité ne libère pas les ressources tant qu'elle n'est pas terminée. Mais dans la plupart des cas, ce ne doit pas être un problème pour vous. À mon avis, vous ne devriez pas ajouter votre propre gestion des ressources et rendre votre code compliqué dans la plupart des cas.
Mais si vous pensez vraiment que votre application peut-être de mémoire, vous devriez vérifier avec quelque chose comme MAT. Les problèmes avec la mémoire peuvent être causés par des fuites de mémoire, pas l'utilisation de mémoire lourde.
éventuellement, quand vous êtes absolument sûr que vous devez faire quelque chose pour réduire l'utilisation de la mémoire, vous pouvez faire une certaine optimisation de la mémoire. Par exemple, vous pouvez enregistrer des objets consommant de la mémoire (par exemple de grandes images) dans le stockage local en onStop()
et onStart()
. Je pense à l'aide de onPause()
/onResume()
pour cela est une mauvaise idée, car l'Activité est partiellement ou même entièrement visible.
En théorie, vous pouvez même détruire tous vos widgets onStop()
et les restaurer en onStart()
, mais il peut rendre votre application trop lente. Et, bien sûr, dans ce la sauvegarde de l'état du cas doit être implémentée par vous.
terminer les activités peut sembler être une bonne idée, mais je pense que ce n'est pas le cas. Premièrement, cela rend votre travail plus lent. Deuxièmement, vous devez gérer vous-même la pile d'activités et l'état des activités. Par exemple, L'activité a commence L'activité B. Ainsi, L'activité b doit savoir quoi faire lorsque l'utilisateur appuie sur le bouton Précédent. Lorsque l'utilisateur appuie sur le bouton de retour, vous devriez commencer L'activité a et restaurer son état. Mais que faire si l'Utilisateur termine cette application. Dans ce cas, vous devez initialiser Une Activité avec son état par défaut. Donc, vous devez mettre en œuvre beaucoup de logique supplémentaire.
en conclusion je vais répéter l'idée principale encore une fois: ne pas optimiser l'utilisation de la mémoire si vous n'êtes pas absolument sûr que vous devez le faire!
Ok, donc, nous avons la situation suivante:
A > onCreate
A > onStart
A > onResume
A > Use up a load of memory (A could even use up too much and crash)
A > Launch activity B
B > onCreate
A > onPause
B > onStart
A > onStop
B > onResume
B > Use up a load of memory
Si B utilise suffisamment de mémoire, alors le système Android va tuer l'activité A (vous remarquerez que les méthodes onPause et onStop de A ont déjà été appelées, donc il a déjà été donné une chance de sauver son état)
si vous appuyez ensuite sur le bouton arrière, Le système Android va juste recommencer l'activité A (et s'il est intelligent, il devrait se souvenir de son dernier état) donc il semble que rien n'est jamais arrivé à la utilisateur.
donc pour être un peu plus clair: si vous commencez B et puis terminer A, B va essentiellement remplacer A dans la pile d'activités et en appuyant sur le bouton arrière dans l'activité B va juste sortir votre et app et retournez à l'activité A.
si d'un autre côté vous commencez B sans finir A, puis appuyez sur le bouton arrière dans B vous ramener à A. pendant que l'activité A est à l'arrière-plan il pourrait être tué pour récupérer la mémoire, mais Androïde va recréer au besoin lorsque l'utilisateur navigue dans la pile d'activités.
aussi si vous avez en mémoire-des caches de plusieurs objets (par exemple bitmaps/drawables) alors sauvegardez votre collection par SoftReferences afin que le GC puisse les effacer si elle est à court de mémoire.
vous devriez concevoir votre application de sorte que son utilisation de la mémoire est faible, mais vous pouvez compter sur le cadre faire c'est mieux dans la gestion de la mémoire. Ainsi, ne pas travailler trop dur avec enlever les choses inutilisées, seulement dans les cas où il est évident que votre application mange trop de mémoire.
lorsque la mémoire disponible tombe en panne, le framework arrête et supprime les activités et les services qui ne sont pas associés à la tâche actuelle. Si votre application consomme encore plus de mémoire, le cadre arrêtera votre les activités qui sont en arrière-plan. Puis vient les services associés à votre application et le dernier à finir sera l'activité en cours.
lorsque le framework arrête une activité, il conserve un enregistrement de la pile d'activités, les intentions utilisées pour démarrer l'activité et le faisceau retourné par onSaveInstanceState (), afin qu'il puisse recréer le dernier état connu des activités. De plus, le cadre peut décharger des ressources inutilisées (tirages, etc.) lorsqu'ils ne sont pas utilisés et les recharger en cas de besoin.
Bien avant de répondre à vos questions, j'ai certains faits pour discuter.
selon le cycle de vie de l'Activité, si nous appelons
finish()
puisonStop()
appelé et enfin l'onDestroy()
qui permet cette activité pour la collecte des ordures et de retirer de la pile D'activité D'Androïde.Android maintient le cache dessinable pour l'activité de conception et d'affichage sur l'écran. Donc si vous désactivez le cache dessinable sur l'Activité
onCreate()
.
donc la meilleure pratique est de désactiver le cache dessinable sur le onCreate
comme ceci:
LinearLayout v = (LinearLayout) findViewById(R.id.mainLayout);
v.setDrawingCacheEnabled(false);
et pour appeler finish();
sur le onPause()
;
vous avez très peu de contrôle sur la mémoire lorsque vous écrivez du code Java. C'est une bonne chose pour la plupart des cas. En fait, la plupart de l'application n'ont pas besoin de se soucier de la mémoire.
pour répondre à votre question, tout l'objet de l'activité A restera en mémoire lorsqu'il sera suspendu. VM lancera GC quand il aura besoin de ressources.