Жизненный цикл фрагмента,Жизненный цикл фрагмента

Каждый экземпляр Fragment имеет свой жизненный цикл. Когда пользователь перемещается по вашему приложению и взаимодействует с ним, ваши фрагменты переходят через различные состояния своего жизненного цикла по мере их добавления, удаления, выхода на экран или выхода из него.

Для управления жизненным циклом Fragment реализует LifecycleOwner , предоставляя объект Lifecycle , к которому вы можете получить доступ через метод getLifecycle() .

Каждое возможное состояние Lifecycle представлено в перечислении Lifecycle.State .

Создавая Fragment поверх Lifecycle , вы можете использовать методы и классы, доступные для обработки жизненных циклов с помощью компонентов, учитывающих жизненный цикл . Например, вы можете отобразить местоположение устройства на экране, используя компонент, учитывающий жизненный цикл. Этот компонент может автоматически начинать прослушивание, когда фрагмент становится активным, и прекращать, когда фрагмент переходит в неактивное состояние.

В качестве альтернативы использованию LifecycleObserver класс Fragment включает методы обратного вызова, соответствующие каждому изменению жизненного цикла фрагмента. К ним относятся onCreate() , onStart() , onResume() , onPause() , onStop() и onDestroy() .

Представление фрагмента имеет отдельный Lifecycle , который управляется независимо от Lifecycle фрагмента. Фрагменты поддерживают LifecycleOwner для своего представления, доступ к которому можно получить с помощью getViewLifecycleOwner() или getViewLifecycleOwnerLiveData() . Доступ к Lifecycle представления полезен в ситуациях, когда компонент, поддерживающий жизненный цикл, должен выполнять работу только до тех пор, пока существует представление фрагмента, например, наблюдение за LiveData , которое предназначено только для отображения на экране.

В этом разделе подробно обсуждается жизненный цикл Fragment , объясняются некоторые правила, определяющие состояние жизненного цикла фрагмента, и показывается взаимосвязь между состояниями Lifecycle и обратными вызовами жизненного цикла фрагмента.

Фрагменты и менеджер фрагментов

Когда создается экземпляр фрагмента, он начинается в состоянии INITIALIZED . Чтобы фрагмент мог пройти оставшуюся часть своего жизненного цикла, его необходимо добавить в FragmentManager . FragmentManager отвечает за определение того, в каком состоянии должен находиться его фрагмент, а затем переводит его в это состояние.

Помимо жизненного цикла фрагмента, FragmentManager также отвечает за прикрепление фрагментов к активности их узла и их отсоединение, когда фрагмент больше не используется. Класс Fragment имеет два метода обратного вызова, onAttach() и onDetach() , которые вы можете переопределить для выполнения работы при возникновении любого из этих событий.

Обратный вызов onAttach() вызывается, когда фрагмент добавлен в FragmentManager и прикреплен к активности своего хоста. На этом этапе фрагмент активен, и FragmentManager управляет состоянием его жизненного цикла. На этом этапе методы FragmentManager , такие как findFragmentById() возвращают этот фрагмент.

onAttach() всегда вызывается перед изменением состояния жизненного цикла .

Обратный вызов onDetach() вызывается, когда фрагмент был удален из FragmentManager и отсоединен от активности своего хоста. Фрагмент больше не активен и его больше нельзя получить с помощью findFragmentById() .

onDetach() всегда вызывается после любого изменения состояния жизненного цикла .

Обратите внимание, что эти обратные вызовы не связаны с методами FragmentTransaction attach() и detach() . Дополнительные сведения об этих методах см. в разделе Транзакции фрагментов .

Состояния жизненного цикла фрагментов и обратные вызовы

При определении состояния жизненного цикла фрагмента FragmentManager учитывает следующее:

  • Максимальное состояние фрагмента определяется его FragmentManager . Фрагмент не может выйти за пределы состояния своего FragmentManager .
  • В рамках FragmentTransaction вы можете установить максимальное состояние жизненного цикла фрагмента с помощью setMaxLifecycle() .
  • Состояние жизненного цикла фрагмента никогда не может быть больше, чем состояние его родителя. Например, родительский фрагмент или действие должны быть запущены раньше его дочерних фрагментов. Аналогично, дочерние фрагменты должны быть остановлены перед родительским фрагментом или действием.
Состояния жизненного цикла фрагмента и их связь, как обратные вызовы жизненного цикла фрагмента, так и жизненный цикл представления фрагмента
Рисунок 1. Состояния Lifecycle фрагмента и их связь как с обратными вызовами жизненного цикла фрагмента, так и с представлением Lifecycle фрагмента.

На рисунке 1 показано каждое из состояний Lifecycle фрагмента и то, как они связаны как с обратными вызовами жизненного цикла фрагмента, так и с представлением Lifecycle фрагмента.

По мере продвижения фрагмента по жизненному циклу он перемещается вверх и вниз по своим состояниям. Например, фрагмент, добавленный в начало заднего стека, перемещается вверх от CREATED к STARTED и к RESUMED . И наоборот, когда фрагмент извлекается из заднего стека, он перемещается вниз по этим состояниям, переходя от RESUMED к STARTED , CREATED и, наконец, DESTROYED .

Переходы состояний вверх

При движении вверх по состояниям жизненного цикла фрагмент сначала вызывает соответствующий обратный вызов жизненного цикла для своего нового состояния. После завершения этого обратного вызова соответствующее событие Lifecycle.Event выдается наблюдателям с помощью Lifecycle фрагмента, за которым следует представление Lifecycle фрагмента, если оно было создано.

Фрагмент СОЗДАН

Когда ваш фрагмент достигает состояния CREATED , он добавляется в FragmentManager и метод onAttach() уже вызывается.

Это подходящее место для восстановления любого сохраненного состояния, связанного с самим фрагментом, через SavedStateRegistry фрагмента. Обратите внимание, что представление фрагмента на данный момент не создано, и любое состояние, связанное с представлением фрагмента, должно быть восстановлено только после создания представления.

Этот переход вызывает обратный вызов onCreate() . Обратный вызов также получает аргумент savedInstanceState Bundle , содержащий любое состояние, ранее сохраненное с помощью onSaveInstanceState() . Обратите внимание, что savedInstanceState имеет null значение при первом создании фрагмента, но оно всегда ненулевое для последующих воссозданий, даже если вы не переопределяете onSaveInstanceState() . Подробнее см. в разделе Сохранение состояния с фрагментами .

Фрагмент СОЗДАН и просмотр ИНИЦИАЛИЗИРОВАН.

Lifecycle представления фрагмента создается только тогда, когда ваш Fragment предоставляет действительный экземпляр View . В большинстве случаев вы можете использовать конструкторы фрагментов , которые принимают @LayoutId , который автоматически расширяет представление в нужное время. Вы также можете переопределить onCreateView() чтобы программно раздуть или создать представление вашего фрагмента.

Если и только если представление вашего фрагмента создается с помощью ненулевого View , это View устанавливается во фрагменте и может быть получено с помощью getView() . Затем getViewLifecycleOwnerLiveData() обновляется новым INITIALIZED LifecycleOwner соответствующим представлению фрагмента. В это время также вызывается обратный вызов жизненного цикла onViewCreated() .

Это подходящее место для настройки начального состояния вашего представления, начала наблюдения за экземплярами LiveData , обратные вызовы которых обновляют представление фрагмента, а также для настройки адаптеров для любых экземпляров RecyclerView или ViewPager2 в представлении вашего фрагмента.

Фрагмент и просмотр CREATED

После создания представления фрагмента предыдущее состояние представления, если оно было, восстанавливается, а затем Lifecycle представления перемещается в состояние CREATED . Владелец жизненного цикла представления также отправляет событие ON_CREATE своим наблюдателям. Здесь вам следует восстановить любое дополнительное состояние, связанное с представлением фрагмента.

Этот переход также вызывает обратный вызов onViewStateRestored() .

Фрагментировать и просматривать НАЧАЛО

Настоятельно рекомендуется привязывать компоненты, поддерживающие жизненный цикл , к состоянию STARTED фрагмента, поскольку это состояние гарантирует, что представление фрагмента доступно, если оно было создано, и что безопасно выполнять FragmentTransaction для дочернего FragmentManager фрагмента. . Если представление фрагмента не равно NULL, Lifecycle представления фрагмента перемещается в STARTED сразу после того, как Lifecycle фрагмента перемещается в STARTED .

Когда фрагмент становится STARTED , вызывается обратный вызов onStart() .

Фрагментирование и просмотр ВОЗОБНОВЛЕНО

Когда фрагмент станет видимым, все эффекты Animator и Transition завершены, и фрагмент готов к взаимодействию с пользователем. Lifecycle фрагмента переходит в состояние RESUMED , и вызывается обратный вызов onResume() .

Переход к RESUMED является подходящим сигналом, указывающим на то, что пользователь теперь может взаимодействовать с вашим фрагментом. Фрагменты, которые не RESUMED , не должны вручную устанавливать фокус на своих представлениях или пытаться управлять видимостью метода ввода .

Переходы состояний вниз

Когда фрагмент перемещается вниз в состояние более низкого жизненного цикла, соответствующее событие Lifecycle.Event выдается наблюдателям представлением фрагмента Lifecycle , если оно создано, за которым следует Lifecycle фрагмента. После того, как событие жизненного цикла фрагмента генерируется, фрагмент вызывает соответствующий обратный вызов жизненного цикла.

Фрагментировать и просматривать НАЧАЛО

Когда пользователь начинает покидать фрагмент, и пока фрагмент все еще виден, Lifecycle цикл фрагмента и его представления возвращается в состояние STARTED и выдает событие ON_PAUSE своим наблюдателям. Затем фрагмент вызывает обратный вызов onPause() .

Фрагмент и просмотр CREATED

Как только фрагмент перестанет быть видимым, Lifecycle цикл фрагмента и его представления переводится в состояние CREATED и отправляет событие ON_STOP своим наблюдателям. Этот переход состояния инициируется не только остановкой родительского действия или фрагмента, но также сохранением состояния родительским действием или фрагментом. Такое поведение гарантирует, что событие ON_STOP будет вызвано до сохранения состояния фрагмента. Это делает событие ON_STOP последней точкой, где можно безопасно выполнить FragmentTransaction для дочернего FragmentManager .

Как показано на рисунке 2, порядок обратного вызова onStop() и сохранения состояния с помощью onSaveInstanceState() различается в зависимости от уровня API. Для всех уровней API до API 28 onSaveInstanceState() вызывается перед onStop() . Для уровней API 28 и выше порядок вызова обратный.

различия в порядке вызова для onStop() и onSaveInstanceState()
Рисунок 2. Различия в порядке вызова onStop() и onSaveInstanceState() .

Фрагмент СОЗДАН, а вид УНИЧТОЖЕН.

После завершения всех анимаций выхода и переходов и отсоединения представления фрагмента от окна Lifecycle представления фрагмента перемещается в состояние DESTROYED и выдает событие ON_DESTROY своим наблюдателям. Затем фрагмент вызывает обратный вызов onDestroyView() . На этом этапе представление фрагмента достигло конца своего жизненного цикла, и getViewLifecycleOwnerLiveData() возвращает null значение.

На этом этапе все ссылки на представление фрагмента должны быть удалены, что позволит выполнить сборку мусора.

Фрагмент УНИЧТОЖЕН

Если фрагмент удален или FragmentManager уничтожен, Lifecycle фрагмента переходит в состояние DESTROYED и отправляет событие ON_DESTROY своим наблюдателям. Затем фрагмент вызывает обратный вызов onDestroy() . На данный момент фрагмент достиг конца своего жизненного цикла.

Дополнительные ресурсы

Дополнительные сведения о жизненном цикле фрагмента см. в следующих дополнительных ресурсах.

Путеводители

Блоги