Почему нельзя передавать параметры фрагменту через конструктор в Android
Что проверяют
Знаете ли вы, что фрагмент пересоздаёт система, а не ваш код, и что именно переживает пересоздание. Это проверка на понимание жизненного цикла и на опыт разбора падений после смерти процесса.
Как отвечать
Фрагмент восстанавливается фреймворком через конструктор без аргументов: при повороте, при возврате со стека, после того как система убила процесс в фоне. Всё, что вы положили в поля своим конструктором, в этот момент не восстанавливается: экземпляр создан заново, поля пусты, экран падает или показывает пустоту.
Пересоздание переживают аргументы. Их кладут в Bundle, фреймворк сохраняет его вместе с состоянием и отдаёт новому экземпляру.
fun newInstance(orderId: Long) = OrderFragment().apply {
arguments = bundleOf(ARG_ID to orderId)
}Если в проекте Navigation, то же самое делает Safe Args, только аргументы получаются типизированными.
Отдельно стоит сказать про FragmentFactory: она разрешает конструкторы с параметрами, и через неё удобно прокидывать зависимости из графа. Но данные конкретного экрана всё равно едут аргументами: фабрика знает, откуда взять репозиторий, и не знает, какой заказ был открыт до того, как процесс убили.
Где спотыкаются
Говорят, что пересоздание бывает при повороте, и предлагают закрыть вопрос через configChanges. Поворот это самый безобидный случай, а смерть процесса в фоне не отключается ничем, и падают такие экраны именно на ней, у пользователей, а не на столе разработчика.
Второе: в аргументы кладут тяжёлое, список моделей или картинку. Транзакция едет через биндер с ограничением около мегабайта на всю транзакцию, и приложение валится с TransactionTooLargeException. В аргументах место идентификаторам, а данные по ним тянет ViewModel.
Третье: услышав про FragmentFactory, решают, что аргументы больше не нужны. Фабрика подставляет зависимости, а не состояние экрана, и после восстановления фрагмент снова окажется без идентификатора.