StateFlow

A Flow That Holds a Value

StateFlow<T> is a hot flow that always has a current value. New collectors immediately get the latest value, then every change. It is the standard way to expose UI state from a ViewModel.

  • Always has a value (needs an initial value).
  • Skips values equal to the current one (equals).
  • Is conflated: a slow collector sees only the latest value, not every intermediate one.
  • Never completes.

Example

Example

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    val cartCount = MutableStateFlow(0)
    val ui = launch { cartCount.collect { println("Badge shows $it") } }
    delay(10)

    cartCount.value = 1; delay(10)
    cartCount.value = 1; delay(10)            // same value: not emitted
    cartCount.update { it + 2 }; delay(10)    // atomic read-modify-write

    // three quick changes without suspending: collector sees only the last
    cartCount.value = 4
    cartCount.value = 5
    cartCount.value = 6
    delay(10)

    println("Current value: ${cartCount.value}")
    ui.cancel()
}

Output

Badge shows 0
Badge shows 1
Badge shows 3
Badge shows 6
Current value: 6

Read-only Exposure

class CartViewModel : ViewModel() {
    private val _count = MutableStateFlow(0)          // private, mutable
    val count: StateFlow<Int> = _count.asStateFlow()  // public, read-only

    fun add() = _count.update { it + 1 }              // thread-safe
}

Tip: Use update { } instead of value = value + 1. update retries atomically if two coroutines change the state at the same time.