Как относиться к глобальным изменениям состояния в приложении
Что проверяют
Держите ли вы глобальное состояние под контролем: где оно хранится, кто вправе его менять и как экраны узнают об изменениях. Следом обычно спрашивают, что станет с этим состоянием после смерти процесса и почему в новом коде берут StateFlow, а не LiveData.
Как отвечать
Позиция: глобального изменяемого состояния должно быть минимум, и у каждого куска один источник правды. Типичные примеры: сессия пользователя, тема, язык, флаги функций, корзина.
Каркас на современном стеке:
- хранение в слое данных: репозиторий с областью
@Singletonв Hilt держитMutableStateFlowприватно и отдаёт наружуStateFlowтолько для чтения. Менять состояние можно лишь его методами; - атомарные изменения:
_state.update { it.copy(...) }вместо чтения и записи отдельными шагами, иначе из двух параллельных обновлений одно потеряется; - постоянные данные: DataStore и Room сами отдают
Flow, и изменение доходит до всех подписчиков без ручных уведомлений; - однонаправленный поток: ViewModel собирает нужные потоки через
combineи публикует одинStateFlow<UiState>, экран только отображает его и отправляет события; - подписка с учётом жизненного цикла: в Compose
collectAsStateWithLifecycle(), во ViewrepeatOnLifecycle(Lifecycle.State.STARTED), чтобы экраны в фоне не тратили ресурсы; - разовые события: навигация и тосты не состояние, их передают через
Channelили явно отмечают обработанными вUiState, иначеStateFlowповторит событие после поворота.
Если был такой случай, расскажите о нём со своими цифрами: что было глобальным, какие баги давало и как вы это переделали.
Где спотыкаются
Хранят глобальное состояние в object с изменяемыми полями. Это работает до первой смерти процесса: система восстанавливает экран, синглтон пуст, и приложение падает или показывает гостя вместо вошедшего пользователя.
Предлагают EventBus для рассылки изменений. Сейчас это устаревший подход: связи между компонентами становятся невидимыми, а Flow из репозитория решает ту же задачу с проверкой типов.
Кладут Context активити в синглтон. Это утечка памяти, которую LeakCanary покажет после первого же поворота экрана.