💡 Android/Kotlin: не перезапускайте `Flow` после каждого поворота экрана
Частая ошибка в ViewModel:
val uiState = repository.observeData()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = UiState.Loading
)
У WhileSubscribed() тайм-аут по умолчанию равен нулю. Когда Activity пересоздаётся при повороте экрана, подписчик исчезает, upstream-поток сразу останавливается, а затем запускается заново.
Это может повторно инициировать запросы, чтение базы или тяжёлые вычисления.
Добавьте небольшой период ожидания:
val uiState = repository.observeData()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = UiState.Loading
)
Теперь поток продолжит работать ещё пять секунд после исчезновения последнего подписчика. Этого обычно достаточно, чтобы новая Activity успела подключиться после изменения конфигурации.
В Compose собирайте состояние с учётом жизненного цикла:
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
Получается полезный баланс:
- поворот экрана не перезапускает весь pipeline;
- при реальном уходе со страницы поток остановится;
- ViewModel не тратит ресурсы без активного интерфейса.
5_000 - не магическое значение. Для дорогого подключения его можно увеличить, а для быстрого локального потока - уменьшить.
#Android #Kotlin #StateFlow #JetpackCompose
Частая ошибка в ViewModel:
val uiState = repository.observeData()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = UiState.Loading
)
У WhileSubscribed() тайм-аут по умолчанию равен нулю. Когда Activity пересоздаётся при повороте экрана, подписчик исчезает, upstream-поток сразу останавливается, а затем запускается заново.
Это может повторно инициировать запросы, чтение базы или тяжёлые вычисления.
Добавьте небольшой период ожидания:
val uiState = repository.observeData()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = UiState.Loading
)
Теперь поток продолжит работать ещё пять секунд после исчезновения последнего подписчика. Этого обычно достаточно, чтобы новая Activity успела подключиться после изменения конфигурации.
В Compose собирайте состояние с учётом жизненного цикла:
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
Получается полезный баланс:
- поворот экрана не перезапускает весь pipeline;
- при реальном уходе со страницы поток остановится;
- ViewModel не тратит ресурсы без активного интерфейса.
5_000 - не магическое значение. Для дорогого подключения его можно увеличить, а для быстрого локального потока - уменьшить.
#Android #Kotlin #StateFlow #JetpackCompose