Работал ли со StateFlow

Ответ

Да, работал. StateFlow — это поток данных, который хранит текущее состояние и эмитит его новым подписчикам. Отличается от SharedFlow тем, что всегда имеет начальное значение и хранит только последнее состояние.

val stateFlow = MutableStateFlow(initialValue = 0)

// Подписка
lifecycleScope.launch {
    stateFlow.collect { value ->
        // Обработка нового значения
    }
}

// Обновление значения
stateFlow.value = 1

Особенности:

  • Требует начальное значение.
  • Коллектит только последнее значение (в отличие от SharedFlow).
  • Потококоно безопасный (можно обновлять из любого потока).
  • Можно использовать с repeatOnLifecycle для избежания утечек.

Ответ 18+ 🔞

А, ну вот, работал, говоришь? Ну, давай разберёмся, что это за зверь такой — StateFlow. Представь себе, что это как твой друг, который всегда знает, какой сейчас счёт в футболе, и если ты опоздал на матч, он тебе сразу последний результат вывалит, а не начнёт с нуля пересказывать. Это поток, который хранит последнее состояние и всем новеньким подписчикам его сразу вручает. Главное отличие от его брата-близнеца, SharedFlow, в том, что этому парню обязательно нужно начальное значение, с чего начинать. Без него он как без штанов — никуда.

Вот смотри, как это выглядит в коде, тут всё просто, ёпта:

val stateFlow = MutableStateFlow(initialValue = 0) // Создаём, сказав "начинаем с нуля"

// Подписываемся, чтобы слушать обновления
lifecycleScope.launch {
    stateFlow.collect { value ->
        // Вот тут ловим каждое новое значение и делаем с ним что надо
    }
}

// А вот так это самое состояние обновляем — просто присваиваем новое значение
stateFlow.value = 1

А теперь по пунктам, что тут важно, чтобы не облажаться:

  • Начальное значение — обязательно. Это не тот тип, который может прийти пустым. Сказал initialValue = 0 — всё, теперь у тебя есть отправная точка. Иначе компилятор тебе такого не простит.
  • Коллектит только последнее. Это его фишка. Если ты подписался, а состояние уже десять раз поменялось, ты получишь только самое свежее, одиннадцатое. Никакой истории, как у SharedFlow с его буфером. Он как одноразовая зажигалка — даёт только последнюю искру.
  • Потокобезопасный чувак. Это значит, что ты можешь лезть и менять stateFlow.value хоть из главного потока, хоть из какого-нибудь фонового worker'а — он не сломается и не выкинет тебе кринж. Внутри у него всё прикручено на хороших замках.
  • С жизненным циклом дружит. Чтобы не было утечек памяти (это когда твой коллектор живёт дольше, чем активити, и сосёт ресурсы, как пылесос), обязательно используй repeatOnLifecycle. Это как поставить напоминалку "выключить духовку". Без неё можно наломать таких дров, что потом пол-приложения переписывать.