StateFlow helps you keep track of changing data in your app. It lets parts of your app watch for updates and react right away.
When you want to show live updates on the screen, like a timer or score.
When multiple parts of your app need to know about the same changing data.
When you want to handle user input and update the UI automatically.
When you want to keep your app's state safe and easy to manage.
When you want to avoid manual event handling and use reactive programming.
Syntax
Kotlin
val stateFlow = MutableStateFlow(initialValue)
// To observe changes:
stateFlow.collect { value ->
// react to value
}
// To update value:
stateFlow.value = newValue
MutableStateFlow lets you change the value.
Use collect inside a coroutine to watch for updates.
Examples
Create a StateFlow holding a number and change it.
Collect values from StateFlow inside a coroutine to react to changes.
Kotlin
lifecycleScope.launch {
count.collect { value ->
println("Count is $value")
}
}
Change and read the current value directly.
Kotlin
val stateFlow = MutableStateFlow("Hello")
stateFlow.value = "Hi"println(stateFlow.value)
Sample Program
This program creates a StateFlow holding a number. It watches for changes and prints them. Then it updates the number three times with a delay.
Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val stateFlow = MutableStateFlow(0)
// Launch a coroutine to observe changesval job = launch {
stateFlow.collect { value ->
println("Observed value: $value")
}
}
// Update the stateFlow value
repeat(3) {
delay(500)
stateFlow.value = it + 1
}
job.cancel() // stop collecting
}
OutputSuccess
Important Notes
StateFlow always has a current value you can read anytime.
Collecting from StateFlow must happen inside a coroutine.
Use MutableStateFlow to change the value, but expose it as StateFlow to others for safety.
Summary
StateFlow holds data that changes over time and lets others watch those changes.
Use MutableStateFlow to update data and collect to react to updates.
It helps keep your app's state clear and reactive.
Practice
(1/5)
1. What is the primary purpose of StateFlow in Kotlin?
easy
A. To handle exceptions in coroutines
B. To perform background network requests
C. To create immutable lists
D. To hold and emit observable state updates over time
Solution
Step 1: Understand StateFlow's role
StateFlow is designed to hold a value that can change and notify observers about these changes.
Step 2: Compare with other options
Options B, C, and D describe unrelated tasks like networking, immutable collections, or error handling, which are not StateFlow's purpose.
Final Answer:
To hold and emit observable state updates over time -> Option D
Quick Check:
StateFlow = observable state holder [OK]
Hint: StateFlow = observable state container for updates [OK]
Common Mistakes:
Confusing StateFlow with networking or error handling
Thinking StateFlow creates immutable collections
Assuming StateFlow is for one-time events
2. Which of the following is the correct way to declare a mutable StateFlow holding an integer with initial value 0?
easy
A. val state = StateFlow(0)
B. val state = mutableStateFlowOf(0)
C. val state = MutableStateFlow(0)
D. val state = StateFlow.Mutable(0)
Solution
Step 1: Recall MutableStateFlow syntax
MutableStateFlow is created by calling its constructor with an initial value, e.g., MutableStateFlow(0).
Step 2: Check other options for syntax errors
val state = StateFlow(0) uses StateFlow directly, which is an interface and cannot be instantiated. val state = mutableStateFlowOf(0) uses a non-existent function. val state = StateFlow.Mutable(0) uses invalid syntax.
Hint: Use MutableStateFlow(initialValue) to create mutable state [OK]
Common Mistakes:
Trying to instantiate StateFlow directly
Using incorrect function names like mutableStateFlowOf
Wrong syntax with dot notation on StateFlow
3. What will be printed by the following Kotlin code snippet?
val state = MutableStateFlow(10)
state.value = 20
println(state.value)
medium
A. 20
B. 10
C. null
D. Compilation error
Solution
Step 1: Understand MutableStateFlow value update
MutableStateFlow's value property can be updated directly. Here, state.value is set to 20.
Step 2: Print the updated value
Printing state.value after update will output 20, the new value.
Final Answer:
20 -> Option A
Quick Check:
state.value after update = 20 [OK]
Hint: state.value holds current value, prints updated value [OK]
Common Mistakes:
Expecting old value after update
Confusing value with collect() usage
Thinking it causes compilation error
4. Identify the error in this Kotlin code using StateFlow:
val state = MutableStateFlow(0)
fun updateState(newValue: Int) {
state.emit(newValue)
}
medium
A. emit() cannot be called outside a coroutine
B. MutableStateFlow cannot hold integers
C. state should be declared as StateFlow, not MutableStateFlow
D. updateState must be a suspend function
Solution
Step 1: Check usage of emit()
emit() is a suspend function and must be called from a coroutine or suspend function.
Step 2: Analyze function updateState
updateState is a regular function, so calling emit() here causes a compile error.
Final Answer:
emit() cannot be called outside a coroutine -> Option A
Quick Check:
emit() requires coroutine context [OK]
Hint: emit() needs coroutine; can't call in normal function [OK]
Common Mistakes:
Calling emit() in non-suspend function
Confusing emit() with value assignment
Thinking MutableStateFlow can't hold Int
5. You want to create a Kotlin app state that updates a user's score and notifies UI reactively. Which approach correctly uses StateFlow to update and observe the score?
hard
A. Use a MutableStateFlow<Int> but update score only by calling collect
B. Use a MutableStateFlow<Int> for score, update with score.value = newScore, and collect changes in UI coroutine
C. Use a MutableStateFlow<Int> and update score by creating a new MutableStateFlow each time
D. Use a StateFlow<Int> and update with emit(newScore) in a regular function
Solution
Step 1: Choose correct StateFlow type and update method
MutableStateFlow allows updating the value property directly with score.value = newScore.
Step 2: Observe changes properly in UI
Collecting the StateFlow in a coroutine lets UI react to updates.
Step 3: Eliminate incorrect options
Use a StateFlow<Int> and update with emit(newScore) in a regular function wrongly calls emit() in a regular function. Use a MutableStateFlow<Int> and update score by creating a new MutableStateFlow each time recreates MutableStateFlow unnecessarily. Use a MutableStateFlow<Int> but update score only by calling collect misunderstands collect's role (it's for observing, not updating).
Final Answer:
Use a MutableStateFlow<Int> for score, update with score.value = newScore, and collect changes in UI coroutine -> Option B