TGViewer
Kotlin Kotlin @kotlin_lib · 2.05K subscribers
Post #692 696
🔥 Ваш StateFlow работает вхолостую. Разбираем SharingStarted

Превращение Flow в StateFlow через stateIn - стандартный паттерн в ViewModel. Но третий параметр (started) - это место, где утекают ресурсы процессора и сети.

Смотрим типичный код:


val uiState: StateFlow<UiState> = repository.observeData()
.map { it.toUiState() }
.stateIn(
scope = viewModelScope,
started = SharingStarted.Eagerly, // 👈 Внимание сюда
initialValue = UiState.Loading
)



1. SharingStarted.Eagerly - Режим "Зомби"
Поток запускается сразу при создании класса (ViewModel).
Даже если UI еще не готов, даже если пользователь свернул приложение, даже если экран находится в бекстеке - этот поток активен.
Он качает данные из БД, маппит их, грузит процессор.
Вердикт: Используйте только если данные нужны всегда и немедленно (например, глобальный статус сети), и их обновление дешевое.

2. SharingStarted.Lazily - Режим "Ленивец"
Поток запускается, когда появляется первый подписчик.
Проблема: когда подписчики исчезают (User свернул app), поток не останавливается. Он продолжает молотить в фоне, обновляя кэш, который никто не видит.
Вердикт: Лучше, чем Eagerly, но все еще waste of resources.

3. SharingStarted.WhileSubscribed(5000) - Выбор Сеньора 👑
Поток активен только пока есть подписчики.
Но зачем там магическое число 5000 (5 секунд)?

Сценарий: Поворот экрана (Configuration Change).

1. Activity умирает (Unsubscribe ❌).
2. Activity пересоздается (Subscribe ✅).

Между этими событиями проходит ~50-500 мс.
Если бы таймаута не было (0 мс), поток бы отменился и тут же перезапустился. Это значит:

• Лишний запрос в сеть/БД.
• Мигание UI (Loading -> Content).

Таймаут в 5 секунд дает "буферное время". Если подписчик вернулся в течение 5 секунд - поток даже не заметил разрыва. Данные остались горячими. Если не вернулся (пользователь ушел) - поток умирает и освобождает ресурсы.

⚠️ Нюанс: При использовании WhileSubscribed, если пользователь ушел с экрана на 10 минут и вернулся, поток перезапустится с нуля (re-subscribe to upstream). Убедитесь, что ваш источник данных (Repository) готов к этому (например, имеет кэш), иначе юзер увидит спиннер.

Чек-лист:

• Eagerly: почти никогда.
• Lazily: если данные нужны "навсегда" после первого открытия.
• WhileSubscribed(5000): дефолт для UI.

А вы используете константу 5000 или создаете свои стратегии? 👇

✍️ @kotlin_lib
  • 👍 5
  • 🤮 1
More from @kotlin_lib
  1. Aug 26, 2026🚧 Ваш Mutex тормозит корутины. Как перестать лочить и начать жить Вы пишете многопоточный…
  2. Jul 25, 2026🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.r…
  3. Jul 1, 2026🌪 Ваша дата в опасности: flatMapConcat vs Merge vs Latest Вам нужно взять поток ID-шников…
  4. Jun 24, 2026🤖 Android-приложение — это не только красивый экран. За ним стоят работа с внешним API, з…
  5. Jun 23, 2026🔮 Убийца бойлерплейта: Встречайте Context Parameters (Kotlin 2.x) Мы так привыкли к Depen…
  6. Jun 3, 2026Яндекс обновил Yandex Mobile Ads SDK для монетизации мобильных приложений — и это интересн…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →