Каждый экземпляр 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
фрагмента.
По мере продвижения фрагмента по жизненному циклу он перемещается вверх и вниз по своим состояниям. Например, фрагмент, добавленный в начало заднего стека, перемещается вверх от 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 и выше порядок вызова обратный.
Фрагмент СОЗДАН, а вид УНИЧТОЖЕН.
После завершения всех анимаций выхода и переходов и отсоединения представления фрагмента от окна Lifecycle
представления фрагмента перемещается в состояние DESTROYED
и выдает событие ON_DESTROY
своим наблюдателям. Затем фрагмент вызывает обратный вызов onDestroyView()
. На этом этапе представление фрагмента достигло конца своего жизненного цикла, и getViewLifecycleOwnerLiveData()
возвращает null
значение.
На этом этапе все ссылки на представление фрагмента должны быть удалены, что позволит выполнить сборку мусора.
Фрагмент УНИЧТОЖЕН
Если фрагмент удален или FragmentManager
уничтожен, Lifecycle
фрагмента переходит в состояние DESTROYED
и отправляет событие ON_DESTROY
своим наблюдателям. Затем фрагмент вызывает обратный вызов onDestroy()
. На данный момент фрагмент достиг конца своего жизненного цикла.
Дополнительные ресурсы
Дополнительные сведения о жизненном цикле фрагмента см. в следующих дополнительных ресурсах.