Почему нельзя всегда передавать параметры через конструктор фрагмента
Что проверяют
Знаете ли вы, что фрагменты создаёт система, а не только ваш код. Следом спрашивают, чем newInstance с Bundle лучше и что делать, когда во фрагмент нужна зависимость, а не данные экрана.
Как отвечать
Причина одна и она техническая: при восстановлении состояния (поворот, возврат после смерти процесса, разбор бэкстека) FragmentManager создаёт фрагмент сам, через FragmentFactory и конструктор без аргументов. Ваш конструктор с параметрами не вызывается: если конструктора без аргументов нет, приложение падает с InstantiationException, а если он есть, поля останутся пустыми и упадёт первое же обращение к ним.
- штатный путь: статический
newInstance(id: Long), внутриarguments = bundleOf("id" to id). ЭтотBundleсохраняется и восстанавливается вместе с фрагментом, поэтому после пересоздания данные на месте; - типобезопасно: Safe Args генерирует классы аргументов и делегат
by navArgs(); - дальше по цепочке:
SavedStateHandleвоViewModelподхватывает те же аргументы; - лимит размера: аргументы едут через транзакцию Binder, лимит около 1 МБ, дальше
TransactionTooLargeException. Кладите идентификаторы, а не списки объектов и картинки.
Конструктор с параметрами не запрещён абсолютно: своя FragmentFactory, выставленная в supportFragmentManager до super.onCreate(), создаёт фрагменты сама, и туда можно отдавать зависимости из графа внедрения. Но данным экрана (какой товар открыт) всё равно место в arguments: они должны пережить пересоздание, а фабрика об этом не знает.
Полезная мелочь: arguments выставляются до присоединения фрагмента, после onAttach вызов setArguments бросит IllegalStateException.
Где спотыкаются
Объясняют запрет тем, что «данные потеряются при уничтожении». Формулировка мимо: конструктор просто не будет вызван системой, и падение случится при восстановлении.
Кладут в Bundle тяжёлые Parcelable-объекты и ловят TransactionTooLargeException на реальных данных, которых не было на стенде.
Считают, что FragmentFactory отменяет arguments. Фабрика закрывает вопрос зависимостей, но не вопрос состояния: параметры экрана должны восстанавливаться из Bundle.