← Назад к вопросам

Какие знаешь виды Flow?

2.0 Middle🔥 131 комментариев
#Многопоточность и асинхронность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Виды 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-приложений с современной асинхронной архитектурой.