Что хранится в Back Stack у FragmentManager?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Структура Back Stack FragmentManager
В контексте FragmentManager (и его наследника FragmentManagerImpl), Back Stack (стек возврата) — это специальная структура данных, которая хранит историю операций с фрагментами, позволяя пользователю возвращаться к предыдущим состояниям интерфейса при нажатии кнопки "Назад".
Что конкретно хранится в Back Stack?
Back Stack не хранит сами экземпляры фрагментов напрямую. Вместо этого он содержит записи, известные как BackStackEntry. Каждая такая запись соответствует одной транзакции (или группе транзакций), которая была добавлена в стек с помощью метода addToBackStack(String name). При выполнении транзакции FragmentManager запоминает все изменения (добавления, удаления, замены, присоединения/отсоединения фрагментов) и сохраняет обратный набор команд для отмены этих изменений.
Ключевые элементы, хранящиеся в каждой записи стека:
- Идентификатор транзакции: Уникальный ID, присваиваемый FragmentManager.
- Имя (опциональное): Строка
name, которая была передана вaddToBackStack(). Используется для навигации по стеку (например,popBackStack(String name, int flags)). - Список операций (Op): Внутренний журнал всех команд (
OP_ADD,OP_REPLACE,OP_REMOVE,OP_HIDE,OP_SHOW,OP_DETACH,OP_ATTACH), которые были выполнены в рамках этой транзакции. Каждая операцияOpсодержит ссылку на фрагмент (Fragment), над которым она производилась, и его состояние на момент транзакции. - Состояние фрагментов: Для каждого фрагмента, затронутого транзакцией, сохраняется его состояние (включая View-иерархию через
onSaveInstanceState()), если фрагмент был скрыт (OP_HIDE), отсоединен (OP_DETACH) или удален (OP_REMOVE). Это позволяет восстановить фрагмент в точности том же виде при возврате по стеку.
Пример работы Back Stack
Рассмотрим классический пример замены фрагмента FragmentA на FragmentB с добавлением в Back Stack:
supportFragmentManager.commit {
replace(R.id.fragment_container, FragmentB())
addToBackStack("transaction_to_fragment_b")
}
Что происходит:
- FragmentManager создает объект транзакции.
- Выполняется операция
OP_REPLACE:FragmentA(если он был) удаляется (OP_REMOVE), аFragmentBдобавляется (OP_ADD). - Поскольку вызван
addToBackStack("transaction_to_fragment_b"), FragmentManager сохраняет запись (BackStackRecord) в Back Stack. Эта запись будет содержать:
* Имя: `"transaction_to_fragment_b"`.
* Операцию `OP_REMOVE` для `FragmentA` (с сохранением его состояния).
* Операцию `OP_ADD` для `FragmentB`.
- При нажатии кнопки "Назад" система вызывает
popBackStack(). FragmentManager находит последнюю запись в стеке и применяет обратные операции:FragmentBудаляется (его состояние сохраняется), аFragmentAснова добавляется и восстанавливается из сохраненного состояния.
Важные особенности и различия
-
FragmentManager vs SupportFragmentManager:
android.app.FragmentManager(для нативных фрагментов) иandroidx.fragment.app.FragmentManager(из AndroidX) имеют схожую логику работы Back Stack, но реализация в AndroidX более стабильна и содержит меньше багов. Рекомендуется всегда использовать AndroidX-версию. -
Nested Fragments (вложенные фрагменты): У дочернего фрагмента свой собственный
ChildFragmentManagerи свой независимый Back Stack. Нажатие кнопки "Назад" сначала обрабатывается дочерним менеджером (если его стек не пуст), и только потом — родительским. -
FragmentState: При добавлении транзакции в Back Stack, фрагменты, которые были удалены или отсоединены, переходят в состояние
CREATED(илиINITIALIZING), но не уничтожаются. Их экземпляры остаются привязанными к FragmentManager, и их состояние сохраняется. Только когда FragmentManager будет уничтожен (например, при завершении Activity), а фрагмент не будет находиться в Back Stack, он может быть окончательно уничтожен. -
Управление: Методы
popBackStack(),popBackStackImmediate(),getBackStackEntryCount(),getBackStackEntryAt()позволяют управлять стеком и получать информацию о нем.
Таким образом, Back Stack FragmentManager — это не просто коллекция фрагментов, а журнал обратных операций, хранящий достаточно информации для последовательной отмены транзакций и восстановления предыдущих состояний интерфейса, обеспечивая корректную навигацию.