Понимание фрагмента setRetainInstance(логическое)

Начиная с документации:

public void setRetainInstance (логическое сохранение)

Управляет сохранением экземпляра фрагмента при повторном создании действия (например, после изменения конфигурации). Это можно использовать только с фрагментами, которые не находятся в заднем стеке. Если установлено, жизненный цикл фрагмента будет немного отличаться при воссоздании действия:

  • onDestroy () не будет вызываться (но onDetach() все равно будет, потому что фрагмент отсоединяется от текущей активности).
  • onCreate (Bundle) не будет вызываться, так как фрагмент не создается заново.
  • onAttach (Activity) и onActivityCreated(Bundle) будут по-прежнему вызываться.

У меня есть несколько вопросов:

  • Сохраняет ли фрагмент также свой вид, или он будет воссоздан при изменении конфигурации? Что именно "сохраняется"?

  • Будет ли фрагмент уничтожен, когда пользователь покинет активность?

  • Почему он не работает с фрагментами на заднем стеке?

  • В каких случаях целесообразно использовать этот метод?

4 ответа

Решение

Прежде всего, проверьте мой пост о сохраненных фрагментах. Это может помочь.

Теперь, чтобы ответить на ваши вопросы:

Сохраняет ли фрагмент также свое состояние просмотра, или это будет воссоздано при изменении конфигурации - что именно "сохраняется"?

Да, FragmentСостояние будет сохраняться при изменении конфигурации. В частности, "сохраняется" означает, что фрагмент не будет уничтожен при изменении конфигурации. Это Fragment будет сохранен, даже если изменение конфигурации вызовет Activity быть уничтоженным.

Будет ли фрагмент уничтожен, когда пользователь покинет активность?

Как Activitys, FragmentСистема может быть уничтожена, когда ресурсы памяти невелики. Сохраните ли ваши фрагменты свое состояние экземпляра при изменениях конфигурации, это не повлияет на то, уничтожит ли система Fragmentкогда вы покидаете Activity, Если вы оставите Activity (то есть нажатием кнопки "Домой"), Fragments может быть или не быть уничтожено. Если вы оставите Activity нажав кнопку назад (таким образом, вызывая finish() и эффективно уничтожить Activity), Все Activityприлагается Fragmentтакже будут уничтожены.

Почему он не работает с фрагментами на заднем стеке?

Вероятно, есть несколько причин, почему это не поддерживается, но наиболее очевидная причина для меня заключается в том, что Activity содержит ссылку на FragmentManagerи FragmentManager управляет backstack. То есть, неважно, если вы решите сохранить свой Fragmentили нет, Activity (и, таким образом, FragmentManagerbackstack) будет уничтожен при изменении конфигурации. Другая причина, по которой это может не сработать, заключается в том, что все может стать сложнее, если разрешить существование как сохраненных фрагментов, так и не сохраненных фрагментов в одном и том же обратном стэке.

В каких случаях целесообразно использовать этот метод?

Сохраненные фрагменты могут быть весьма полезны для распространения информации о состоянии, особенно управления потоками, между экземплярами операций. Например, фрагмент может служить хостом для экземпляра Thread или же AsyncTaskУправляя своей работой. Смотрите мой блог на эту тему для получения дополнительной информации.

В общем, я бы отнесся к этому аналогично onConfigurationChanged с Activity... не используйте его в качестве бандажа только потому, что вы слишком ленивы, чтобы правильно реализовать / обработать изменение ориентации. Используйте его только тогда, когда вам нужно.

setRetaininstance полезно только когда ваш activity уничтожается и воссоздается из-за изменения конфигурации, потому что экземпляры сохраняются во время вызова onRetainNonConfigurationInstance, То есть, если вы поверните устройство, сохраненные фрагменты останутся там (они не будут уничтожены и воссозданы). Но когда среда выполнения убивает действие, чтобы вернуть ресурсы, ничего не остается. Когда вы нажимаете кнопку "Назад" и выходите из игры, все разрушается.

Обычно я использую эту функцию, чтобы сохранить изменение ориентации Time. Скажем, я загрузил несколько растровых изображений с сервера, и каждый из них занимает 1 МБ, когда пользователь случайно поворачивает свое устройство, я, конечно, не хочу снова выполнять всю работу по загрузке. Я создаю Fragment держа мои растровые изображения и добавить его к менеджеру и позвонить setRetainInstanceвсе растровые изображения все еще там, даже если ориентация экрана изменяется.

setRetainInstance() - не рекомендуется

В виде фрагментов Версия 1.3.0-alpha01

Метод setRetainInstance() для фрагментов устарел. С введением ViewModels разработчики получили специальный API для сохранения состояния, которое может быть связано с действиями, фрагментами и графами навигации. Это позволяет разработчикам использовать обычный, не сохраняемый фрагмент и сохранять конкретное состояние, которое они хотят сохранить отдельно, избегая общего источника утечек, сохраняя при этом полезные свойства единственного создания и уничтожения сохраненного состояния (а именно, конструктора ViewModel и обратный вызов onCleared(), который он получает).

SetRetainInstance(true) позволяет фрагменту выживать. Его члены будут сохранены во время изменения конфигурации, например, при ротации. Но он все еще может быть убит, когда активность убивается в фоновом режиме. Если содержащая активность в фоновом режиме уничтожена системой, ее instanceState должен быть сохранен системой, которую вы правильно обработали на SaveInstanceState. Другими словами, всегда вызывается onSaveInstanceState. Хотя onCreateView не будет вызываться, если SetRetainInstance имеет значение true, а фрагмент / активность еще не уничтожен, он все равно будет вызываться, если он уничтожен и его пытаются вернуть обратно.

Вот некоторый анализ активности / фрагмента андроида, надеюсь, это поможет. http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html

setRetainInstance(boolean) полезен, когда вы хотите иметь какой-то компонент, который не связан с жизненным циклом Activity. Этот метод используется, например, rxloader для "обработки жизненного цикла активности Android для rxjava's Observable" (который я нашел здесь).

Другие вопросы по тегам