Какие способы передачи данных между фрагментами в Android существуют
Что проверяют
Знаете ли вы актуальные способы и понимаете ли, почему прямая ссылка на соседний фрагмент это плохо.
Как отвечать
Способы, отсортированные по применимости:
- общая ViewModel в области активности или графа навигации:
by activityViewModels()илиby hiltNavGraphViewModels(). Фрагменты не знают друг о друге, оба подписаны на один поток состояния. Это основной способ для связанных экранов; - аргументы фрагмента:
BundleчерезsetArguments, а лучше Safe Args в Navigation Component, который даёт типобезопасность и проверку на этапе сборки. Подходит для передачи вперёд, при создании; - Fragment Result API:
setFragmentResultиsetFragmentResultListenerс общим ключом. Штатная замена устаревшемуsetTargetFragment, работает для возврата результата назад, например из диалога выбора; SavedStateHandleпредыдущей записи в стеке навигации:previousBackStackEntry.savedStateHandle, тоже для возврата результата;- общий репозиторий или слой данных: когда «передача» на самом деле означает изменение состояния приложения, а не разовое сообщение.
Ограничение, которое стоит назвать: Bundle идёт через Binder, а транзакция ограничена по размеру, около мегабайта на процесс. Поэтому в аргументах передают идентификатор, а не объект целиком, и тем более не список.
Что делать нельзя: искать соседний фрагмент через findFragmentByTag и звать его методы, держать ссылку на другой фрагмент в поле, использовать setTargetFragment (объявлен устаревшим).
Где спотыкаются
Передают крупный Parcelable в аргументах и ловят падение.
Используют by viewModels() вместо by activityViewModels() и получают два разных экземпляра.
Держат ссылку на фрагмент и получают утечку после пересоздания.
Шлют событие через общий поток без учёта пересоздания и показывают одно сообщение дважды.