Какие знаешь виды Flow?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Виды Flow в Kotlin Coroutines
В Kotlin Coroutines Flow — это холодный асинхронный поток данных, который может последовательно испускать несколько значений. Вот основные виды Flow, которые важно знать для разработки под Android:
1. Обычный Flow (Cold Flow)
Это базовый тип Flow, который является холодным (cold) — он начинает испускать данные только когда запускается коллектор (collect). Каждый коллектор получает собственную последовательность данных.
fun fetchUserData(): Flow<String> = flow {
emit("Loading...")
delay(1000)
emit(userRepository.getUserData())
delay(500)
emit("Completed")
}
2. StateFlow
StateFlow — это горячий (hot) поток, который хранит текущее состояние и немедленно emits его новым подписчикам. Ключевые особенности:
- Всегда имеет значение (initial value обязательно)
- Кэширует последнее значение
- Отправляет только различающиеся (distinct) значения
- Идеален для представления состояния UI
class UserViewModel : ViewModel() {
private val _userState = MutableStateFlow<UserState>(UserState.Loading)
val userState: StateFlow<UserState> = _userState.asStateFlow()
fun loadUser() {
viewModelScope.launch {
_userState.value = UserState.Success(userRepository.getUser())
}
}
}
3. SharedFlow
SharedFlow — это горячий поток, который может иметь несколько подписчиков и не хранит значение по умолчанию. Особенности:
- Не имеет initial value (кроме конфигурируемого replay)
- Может иметь множество коллекторов
- Поддерживает replay последних значений новым подписчикам
- Используется для событий (events), а не состояния
class EventBus {
private val _events = MutableSharedFlow<AppEvent>()
val events = _events.asSharedFlow()
suspend fun sendEvent(event: AppEvent) {
_events.emit(event)
}
}
4. Конвертированные Flow
Существуют также специализированные виды Flow, создаваемые через операторы:
- ChannelFlow — Flow, который использует Channel для эмита значений, позволяя emit из разных контекстов:
fun observeUserActions(): Flow<UserAction> = channelFlow {
userActionChannel.consumeAsFlow().collect { action ->
send(action)
}
}
- Callback Flow — для обертки callback-based API:
fun locationUpdates(): Flow<Location> = callbackFlow {
val callback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult) {
result.locations.forEach { location ->
trySend(location)
}
}
}
requestLocationUpdates(callback)
awaitClose { removeLocationUpdates(callback) }
}
5. Flow создаваемые операторами
Многие операторы transform создают свои виды Flow:
- Flow.debounce() — испускает значения только после паузы
- Flow.distinctUntilChanged() — фильтрует последовательные дубликаты
- Flow.flatMapLatest() — переключается на новый Flow при новом значении
- Flow.combine() — комбинирует несколько Flow
Ключевые отличия и использование
Холодные vs Горячие Flow:
- Cold Flow (обычный Flow): Данные производятся для каждого коллектора отдельно
- Hot Flow (StateFlow/SharedFlow): Данные производятся независимо от наличия коллекторов
StateFlow vs SharedFlow:
- StateFlow — для состояния (state), имеет текущее значение, обязателен initial value
- SharedFlow — для событий (events), не имеет значения по умолчанию, поддерживает replay
Практическое применение в Android:
- StateFlow в ViewModel для UI состояния
- SharedFlow для одноразовых событий (навигация, показ сообщений)
- Обычный Flow для преобразования данных из repository
- Callback Flow для интеграции с legacy API
Понимание различий между этими видами Flow критически важно для создания отзывчивых, эффективных и корректно работающих Android-приложений с современной асинхронной архитектурой.