Какой паттерн используется для управления состоянием с корутинами в Android
Что проверяют
Знаете ли вы, что StateFlow это инструмент, а паттерн здесь однонаправленный поток данных (UDF) в рамках MVVM или MVI. Интервьюер хочет услышать, как состояние живёт в ViewModel, как UI его безопасно собирает и что делать с одноразовыми событиями. Следом спрашивают про жизненный цикл при сборе потока.
Как отвечать
Опишите схему: UI отправляет действия в ViewModel, та меняет единственный объект состояния, UI его отрисовывает. Детали:
- состояние: неизменяемый
data class UiStateилиsealed interfaceдля вариантов загрузка, данные, ошибка. Наружу отдаётсяStateFlow<UiState>, внутри лежитMutableStateFlow; - обновление:
_state.update { it.copy(isLoading = true) }атомарно, в отличие от раздельного чтения и записиvalue. Для самой записиlaunchне нужен, корутина нужна для вызова репозитория; - состояние из потока:
stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), initial). Пять секунд переживают поворот экрана без перезапуска подписки; - сбор в UI: в Compose
collectAsStateWithLifecycle(), во View-системеrepeatOnLifecycle(Lifecycle.State.STARTED). ГолыйcollectвlifecycleScopeпродолжает работать в фоне; - одноразовые события: навигацию и сообщения передают либо полем в состоянии, которое UI сбрасывает после обработки, либо через
ChannelсreceiveAsFlow(). Рекомендации Android склоняются к первому варианту.
В MVI добавляется явный редьюсер: чистая функция от старого состояния и действия. Её легко тестировать, а для потоков есть runTest и библиотека Turbine.
Где спотыкаются
Держат несколько независимых StateFlow на один экран и получают несогласованные комбинации, например загрузку и ошибку одновременно.
Отправляют навигацию через StateFlow: после поворота экрана новый подписчик получает последнее значение, и переход повторяется.
Не знают, что StateFlow пропускает равные значения: если изменить элемент внутри изменяемого списка и выставить тот же объект, UI не обновится.