Какие виды Flow бывают в Kotlin и в чем их разница
Что проверяют
Понимаете ли вы деление на холодные и горячие потоки и умеете ли выбирать между StateFlow и SharedFlow.
Как отвечать
Холодный Flow это описание вычисления. Код внутри не выполняется, пока кто-то не подписался, и у каждого подписчика своя независимая выдача:
val prices = flow { while (true) { emit(api.load()); delay(5_000) } }Горячие потоки существуют независимо от подписчиков:
- StateFlow: всегда содержит текущее значение, новый подписчик сразу получает его. Отбрасывает повторы, равные предыдущему значению. Это состояние экрана;
- SharedFlow: без обязательного значения, с настраиваемым буфером и повтором для новых подписчиков. Это события: показать сообщение, перейти на экран.
Разница на практике важна именно здесь: положишь событие в StateFlow, и после поворота экрана подписчик получит его снова, показав тост второй раз. Положишь состояние в SharedFlow без повтора, и новый подписчик не увидит ничего, пока не придёт следующее значение.
Холодный превращается в горячий через shareIn и stateIn, обычно с SharingStarted.WhileSubscribed(5000), чтобы поток не работал вхолостую при уходе с экрана и переживал поворот.
Полезно назвать и операторы: map, filter, combine, flatMapLatest (отменяет предыдущий, идеален для поиска по вводу), debounce, distinctUntilChanged, catch и flowOn для смены контекста выше по цепочке.
Где спотыкаются
Отдают одноразовые события через StateFlow и получают повтор после поворота.
Не отменяют подписку, собирая поток вне repeatOnLifecycle.
Считают, что flowOn меняет контекст всей цепочки, а он влияет только на то, что выше него.
Не знают, что у StateFlow есть встроенный distinctUntilChanged, и удивляются пропущенным одинаковым значениям.