71 votes

Lorsqu'un fragment est remplacé et mis dans la pile arrière (ou supprimé), reste-t-il en mémoire?

Est le comportement similaire à la façon dont les Activités de travail? Par exemple avec des Activités il fonctionne comme ceci:

L'activité commence Activité B, tandis que B est sur l'écran, le système est capable de supprimer Un à partir de la mémoire si elle est requise par le système. En appuyant sur l'ARRIÈRE, UN sera recréé dans la mémoire comme si elle n'a jamais quitté la première place.

J'ai cherché une explication claire de ce qui se passe de la mémoire de la sagesse avec des Fragments et n'ai pas trouvé quoi que ce soit. Cela fonctionne de la même façon? Par exemple:

Activité C a Fragment F dans sa mise en page. Puis, à un certain point F est remplacé par le Fragment G, mais F est conservé dans la pile de retour.

Va F reste en mémoire jusqu'à ce que la C est tué ou peut-il être retiré par le système en cas de besoin?

Vraiment ce que je demande est de savoir si ou de ne pas courir le risque de manquer de mémoire si j'ai une pile de retour de Fragments complexes en une seule Activité?

101voto

Ivan Bartsov Points 4689

Jetez un oeil à ceci: BackStackRecord.Op.fragment

C'est la façon dont les fragments sont stockées dans la pile de retour. Remarque le live de référence, ni WeakReference ni SoftReference y sont utilisées.

Maintenant ceci: FragmentManagerImpl.mBackStack

C'est là que le gestionnaire de magasins de la pile de retour. Simple liste de tableaux, aussi, pas de représentants de l'oms ou de la SRs.

Et finalement, c': Activité.mFragments

C'est la référence au fragment de manager.

GC ne peut collecter des objets qui n'ont pas de vivre références (non accessible à partir de n'importe quel thread). Cela signifie que, jusqu'à ce que votre Activité est détruit (et donc, FragmentManager référence a disparu), la GC ne sera pas en mesure de recueillir tous les Fragments de la pile de retour.

Notez que lorsque l'Activité est détruite et conserve l'état (comme lorsque vous mettez l'appareil en mode paysage), il ne conserve pas l'exact du Fragment objets dans la pile, seuls les états - Fragment.FragmentState objets, c'est à dire réelle des fragments de la pile de retour sont recréés à chaque fois que l'activité est re-créé avec retenues de l'état.

Espérons que cette aide.

PS Donc, en résumé: Oui, vous pouvez exécuter de mémoire par l'ajout de Fragments de pile de retour ainsi que par l'ajout de trop nombreux points de vue pour afficher la hiérarchie.

UPD , compte tenu de votre exemple, F restera dans la mémoire jusqu'à ce que C est tué. Si C est tué puis ressuscité avec différentes configuration - F sera détruit et réincarné dans un autre objet. Donc, F est empreinte mémoire est autour jusqu'à ce que C perd de l'état ou à l'arrière de la pile est désactivée.

7voto

Beowulf Bjornson Points 1166

Je suis désolé de ne pas être en mesure de vous fournir certaines des informations officielles, mais j'étais curieux aussi de voir ce qui allait se passer et a décidé de le tester. Et d'après mes tests, oui, vous courez le risque de manquer de mémoire.

J'ai dû ajouter une quantité incroyable de Fragments (plus d'une centaine) dans une boucle for pour l' OutOfMemoryError arriver, mais c'est arrivé. Et la vérification de mes logs, j'ai pu voir que l' onCreate() et onCreateView() méthodes ont été appelés un lot de fois, mais onSaveInstance(), onPause() et onDestroy n'étaient pas appelés à tous.

Pour référence, c'est comment j'ai ajouté les fragments de la backstack:

getSupportFragmentManager().beginTransaction().add(R.id.scene_fragment_container, mSceneFragment).addToBackStack("FOOBAR").commit();

Et les Fragments que j'ai ajouté sont quelque chose de simple: un ImageView, EditText, un couple, TextViews, SeekBar et ListView.

Mais, sauf si vous êtes titulaire d'une énorme quantité de données dans la mémoire, il ne devrait pas être un problème.

Plus tard, j'ai essayé d'ajouter à seulement 50 pour la backstack, tuant l'application et de la relancer. Et comme je l'ai espéré/deviné, tous les fragments ont été restaurées (et l' onSaveInstance() et onPause() méthodes appelées) donc mon cycle de vie mise en œuvre n'était pas le problème qui a causé l' OutOfMemoryError de le feu.

4voto

Bill Gary Points 2638

À partir de developer.android.com/guide/topics/fundamentals/fragments.html

Un fragment doit toujours être incorporé dans une activité et le fragment du cycle de vie est directement affectée par l'activité de l'hôte du cycle de vie. Par exemple, lorsque l'activité est suspendue, ce sont donc tous les fragments, et lorsque l'activité est détruite, ce sont donc tous les fragments. Toutefois, alors que l'activité est en cours d'exécution (c'est dans le cadre de la reprise du cycle de vie de l'état), vous pouvez manipuler chaque fragment de façon indépendante, comme les ajouter ou les supprimer. Lorsque vous effectuez un tel fragment de la transaction, vous pouvez également l'ajouter à une pile de retour qui est géré par l'activité de chaque pile de retour d'entrée dans l'activité est un enregistrement de l'extrait de la transaction qui a eu lieu. La pile de retour permet à l'utilisateur d'inverser un fragment de transaction (naviguer vers l'arrière), en appuyant sur le bouton RETOUR.

1voto

Sid Points 4070

Oui, vous pouvez manquer de mémoire et créer trop de fragments dans une seule activité. Les fragments ne seront détruits que lorsque l'activité contenante est.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X