Какие проблемы могут возникнуть при приватном конструкторе фрагмента
Что проверяют
Знаете ли вы, как система пересоздаёт фрагмент, и понимаете ли, почему ошибка всплывает не сразу. Следом обычно спрашивают, как тогда передать во фрагмент аргументы и зависимости.
Как отвечать
Главное: после поворота экрана, смены темы или гибели процесса FragmentManager восстанавливает фрагменты сам, по имени класса. Стандартная FragmentFactory ищет публичный конструктор без аргументов через рефлексию. С приватным конструктором приложение падает с Fragment.InstantiationException и сообщением, что конструктор не найден.
Коварство в том, что первый показ проходит: фабричный метод внутри класса видит приватный конструктор. Падение случается позже, поэтому проверяйте с опцией разработчика «Не сохранять действия» (Don't keep activities) или через adb shell am kill для приложения в фоне. Сам класс тоже должен быть публичным, а в Kotlin не inner class.
Как делать правильно:
- аргументы: публичный пустой конструктор плюс
newInstance()вcompanion object, который кладёт данные вarguments = bundleOf(...).Bundleсохраняется и возвращается фрагменту после пересоздания; - зависимости через конструктор: своя
FragmentFactory, установленная вsupportFragmentManager.fragmentFactoryдоsuper.onCreate(), иначе при восстановлении сработает стандартная; - DI: Hilt с
@AndroidEntryPointвнедряет зависимости в поля, конструктор остаётся пустым; - навигация: Navigation Component сам создаёт фрагмент и передаёт аргументы, с Safe Args они ещё и типизированы;
- тесты:
launchFragmentInContainerизfragment-testingпринимает свою фабрику.
Где спотыкаются
Говорят «у меня всё работает», проверив только обычный запуск. Краш приходит от пользователей, которые свернули приложение и вернулись через час.
Передают данные через сеттеры или поля после создания. После пересоздания эти поля пустые, а arguments бы сохранились.
Называют onActivityCreated() местом для инициализации. Он давно помечен устаревшим, код переносят в onViewCreated() или подписываются на жизненный цикл активности.