← Назад к вопросам

Что хранится в Back Stack у FragmentManager?

3.0 Senior🔥 22 комментариев
#Архитектура и паттерны#Жизненный цикл и навигация

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Структура Back Stack FragmentManager

В контексте FragmentManager (и его наследника FragmentManagerImpl), Back Stack (стек возврата) — это специальная структура данных, которая хранит историю операций с фрагментами, позволяя пользователю возвращаться к предыдущим состояниям интерфейса при нажатии кнопки "Назад".

Что конкретно хранится в Back Stack?

Back Stack не хранит сами экземпляры фрагментов напрямую. Вместо этого он содержит записи, известные как BackStackEntry. Каждая такая запись соответствует одной транзакции (или группе транзакций), которая была добавлена в стек с помощью метода addToBackStack(String name). При выполнении транзакции FragmentManager запоминает все изменения (добавления, удаления, замены, присоединения/отсоединения фрагментов) и сохраняет обратный набор команд для отмены этих изменений.

Ключевые элементы, хранящиеся в каждой записи стека:

  1. Идентификатор транзакции: Уникальный ID, присваиваемый FragmentManager.
  2. Имя (опциональное): Строка name, которая была передана в addToBackStack(). Используется для навигации по стеку (например, popBackStack(String name, int flags)).
  3. Список операций (Op): Внутренний журнал всех команд (OP_ADD, OP_REPLACE, OP_REMOVE, OP_HIDE, OP_SHOW, OP_DETACH, OP_ATTACH), которые были выполнены в рамках этой транзакции. Каждая операция Op содержит ссылку на фрагмент (Fragment), над которым она производилась, и его состояние на момент транзакции.
  4. Состояние фрагментов: Для каждого фрагмента, затронутого транзакцией, сохраняется его состояние (включая 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")
}

Что происходит:

  1. FragmentManager создает объект транзакции.
  2. Выполняется операция OP_REPLACE: FragmentA (если он был) удаляется (OP_REMOVE), а FragmentB добавляется (OP_ADD).
  3. Поскольку вызван addToBackStack("transaction_to_fragment_b"), FragmentManager сохраняет запись (BackStackRecord) в Back Stack. Эта запись будет содержать:
    *   Имя: `"transaction_to_fragment_b"`.
    *   Операцию `OP_REMOVE` для `FragmentA` (с сохранением его состояния).
    *   Операцию `OP_ADD` для `FragmentB`.
  1. При нажатии кнопки "Назад" система вызывает 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 — это не просто коллекция фрагментов, а журнал обратных операций, хранящий достаточно информации для последовательной отмены транзакций и восстановления предыдущих состояний интерфейса, обеспечивая корректную навигацию.

Что хранится в Back Stack у FragmentManager? | PrepBro