Это происходит, когда:
▶️ Fragment
переходит в состояние onDestroyView()
, но не в onDestroy()
Пример:
При навигации внутри ViewPager
(до ViewPager2) или при использовании фрагментов с FragmentTransaction().replace()
/ addToBackStack()
, когда пользователь покидает экран, но Fragment
остаётся в памяти, потому что:
Android освобождает ресурсы UI (View
), но сохраняет сам Fragment
, чтобы быстрее восстановить UI при возврате назад.
Инстанс Fragment
-а всё ещё в back stack’е!
Почему это сделано? Зачем так нужно?
- Экономия памяти
View-иерархия может быть тяжёлой (особенно если в ней RecyclerView, картинки и т.п.). КогдаFragment
не отображается, Android может уничтожитьView
, но оставитьFragment
в памяти — он легче, особенно если в нём только бизнес-логика. - Сохранение бизнес-состояния / данных
Fragment
может содержать:- ссылки на
ViewModel
(черезactivityViewModels()
илиviewModels()
) - состояние, нужное при возвращении на экран
- ссылки на
- Плавный UX при возврате
Когда пользователь возвращается назад (popBackStack()
),Fragment
может восстановитьView
, используя те же данные (из ViewModel или сохранённого состояния).
Вопрос на проверку: «Почему нельзя использовать binding после onDestroyView()?»
Потому что binding больше не ссылается на актуальную View!
Когда вызывается onDestroyView()
, вся иерархия View
фрагмента уничтожается. Если ты попытаешься использовать binding
после этого (например, в onDestroy()
или в callback’е корутины/LiveData), ты получишь:
- ❗
IllegalStateException
: View not attached to window manager - ❗ Потенциальную утечку памяти (если ты хранишь
binding
какval
и не обнуляешь) - ❗ Доступ к null-ссылке или уже переприсвоенной View, если фрагмент пересоздался
Аналогия
Представь, что ты открыл Excel-файл, прочитал из него ссылки на ячейки, а потом удалил файл — попытка использовать эти ссылки приведёт к сбою. То же самое с binding
.