web-dev-qa-db-fra.com

Comprendre le setRetainInstance de Fragment (booléen)

En commençant par la documentation:

public void setRetainInstance (boolean retenue)

Contrôlez si une instance de fragment est conservée lors de la recréation d'activités (par exemple, à la suite d'un changement de configuration). Cela ne peut être utilisé qu'avec des fragments qui ne sont pas dans la pile arrière. Si défini, le cycle de vie des fragments sera légèrement différent lorsqu’une activité est recréée:

  • onDestroy () ne sera pas appelé (mais onDetach () le sera toujours, car le fragment est détaché de son activité actuelle).
  • onCreate (Bundle) ne sera pas appelé car le fragment n'est pas recréé.
  • onAttach (Activity) et onActivityCreated (Bundle) seront toujours appelés.

J'ai quelques questions:

  • Le fragment conserve-t-il également sa vue ou sera-t-il recréé lors d'un changement de configuration? Que signifie exactement "retenu"?

  • Le fragment sera-t-il détruit lorsque l'utilisateur quittera l'activité?

  • Pourquoi cela ne fonctionne-t-il pas avec des fragments sur la pile arrière?

  • Quels sont les cas d'utilisation où il est logique d'utiliser cette méthode?

319
Ixx

Tout d’abord, consultez mon post sur les fragments conservés. Cela pourrait aider.

Maintenant, pour répondre à vos questions:

Le fragment conserve-t-il aussi sa vue état, ou sera-t-il recréé lors du changement de configuration - qu'est-ce exactement "conservé"?

Oui, l'état de Fragment sera conservé lors du changement de configuration. Plus précisément, "retenu" signifie que le fragment ne sera pas détruit lors de modifications de la configuration. Autrement dit, la Fragment sera conservée même si la modification de la configuration entraîne la destruction de la Activity sous-jacente.

Le fragment sera-t-il détruit lorsque l'utilisateur quittera l'activité?

Tout comme Activitys, Fragments peut être détruit par le système lorsque les ressources en mémoire sont faibles. Le fait que vos fragments conservent ou non leur état d'instance lors des modifications de configuration n'aura aucune incidence sur le fait que le système détruira ou non les Fragments une fois que vous quitterez le Activity. Si vous quittez la Activity (c'est-à-dire en appuyant sur la touche d'accueil), le Fragments peut être détruit ou non. Si vous quittez la Activity en appuyant sur le bouton retour (appelez donc finish() et détruisez effectivement la Activity), tous les Activitys attachés Fragments seront également être détruit.

Pourquoi cela ne fonctionne-t-il pas avec des fragments sur la pile arrière?

Il y a probablement plusieurs raisons pour lesquelles il n'est pas pris en charge, mais la raison la plus évidente pour moi est que la Activity contient une référence à la FragmentManager et que la FragmentManager gère le backstack. Autrement dit, que vous choisissiez ou non de conserver votre Fragments, le Activity (et donc le backstack de FragmentManager) sera détruit lors d'un changement de configuration. Une autre raison pour laquelle cela pourrait ne pas fonctionner est que les choses pourraient devenir difficiles si les deux fragments conservés et non-conservés étaient autorisés à exister sur le même backstack.

Quels sont les cas d'utilisation où il est logique d'utiliser cette méthode?

Les fragments conservés peuvent être très utiles pour propager des informations d'état, notamment la gestion de threads, à travers des instances d'activité. Par exemple, un fragment peut servir d’hôte pour une instance de Thread ou AsyncTask, gérant son fonctionnement. Voir mon article de blog sur ce sujet pour plus d'informations.

En général, je le traiterais de la même manière qu'en utilisant onConfigurationChanged avec un Activity... ne l'utilisez pas comme un pansement simplement parce que vous êtes trop paresseux pour implémenter/gérer correctement un changement d'orientation. Utilisez-le uniquement lorsque vous en avez besoin.

325
Alex Lockwood

setRetaininstance n'est utile que lorsque votre activity est détruit et recréé en raison d'un changement de configuration car les instances sont enregistrées lors d'un appel à onRetainNonConfigurationInstance. Autrement dit, si vous faites pivoter le périphérique, les fragments conservés y resteront (ils ne sont ni détruits ni recréés), mais lorsque l'exécution supprime l'activité de récupération des ressources, il ne reste plus rien. Lorsque vous appuyez sur le bouton Retour et que vous quittez l'activité, tout est détruit.

Habituellement, j'utilise cette fonction pour enregistrer l'heure de changement. Indiquez que j'ai téléchargé plusieurs bitmaps depuis le serveur et que chacun fait 1 Mo. Lorsque l'utilisateur fait accidentellement pivoter son appareil, je ne veux certainement pas refaire tout le travail de téléchargement.Ainsi, Je crée un Fragment contenant mes bitmaps, je l'ajoute au gestionnaire et appelle setRetainInstance, tous les bitmaps sont toujours présents, même si l'orientation de l'écran change.

26
suitianshi

SetRetainInstance (true) permet à la sorte de fragment de survivre. Ses membres seront conservés lors du changement de configuration, comme une rotation. Mais il peut toujours être tué lorsque l'activité est éliminée à l'arrière-plan. Si l'activité contenue en arrière-plan est supprimée par le système, c'est instanceState qui devrait être enregistré par le système que vous avez géré correctement onSaveInstanceState. Dans un autre mot, onSaveInstanceState sera toujours appelé. Bien que onCreateView ne sera pas appelé si SetRetainInstance est vrai et que fragment/activity n'est pas encore tué, il sera quand même appelé s'il est tué et que l'on essaie de le ramener.

Voici une analyse de l'activité Android _ et de son fragment. http://ideaventure.blogspot.com.au/2014/01/Android-activityfragment-life-cycle.html

12
Kejun Xia

setRetainInstance (boolean) est utile lorsque vous souhaitez avoir un composant qui n'est pas lié au cycle de vie de l'activité. Cette technique est utilisée par exemple par rxloader pour "gérer le cycle de vie d'activité d'Android pour Observable de rxjava" (que j'ai trouvé ici ).

2
Marian Paździoch