563просмотров
26.6%от подписчиков
24 февраля 2026 г.
Score: 619
🔥 Ваш 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