StateFlow vs. SharedFlow: A Practical Guide
Table of Contents
🌊 The Hot Flow Confusion
In Kotlin Coroutines, we have Flow (cold) and two types of Hot Flows: StateFlow and SharedFlow. Knowing the difference is critical for Android UI development.
Cold Flow
- Starts only when collected.
- Each collector gets a fresh stream.
- Example: Room query, Retrofit call.
Hot Flow
- Always active (depending on scope).
- Multicast (multiple collectors get same updates).
- Example: UI State, Events.
💾 StateFlow: The State Holder
Designed to replace LiveData. It always has a value.
Characteristics
- Initial Value: Mandatory.
- Replay Cache: size = 1 (always emits last value to new subscribers).
- Equality Check: Only emits if value changes (
distinctUntilChanged).
Use Case: UI State
Perfect for holding the current state of a screen (Loading, Content, Error).
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
📡 SharedFlow: The Event Emitter
Designed for one-time events or streams without initial state.
Characteristics
- No Initial Value: Starts empty.
- Configurable Replay: Can replay 0, 1, or N previous values.
- Buffer Overflow: Can drop oldest or suspend.
Use Case: Navigation, Toasts
Perfect for “fire and forget” events.
private val _events = MutableSharedFlow<UiEvent>()
val events: SharedFlow<UiEvent> = _events.asSharedFlow()
// Emitting
_events.emit(UiEvent.ShowToast("Hello"))
⚠️ The Trap: SharedFlow for State
Don’t use SharedFlow for UI state. If the UI collects it after emission (e.g., rotation), the state is lost unless you configure replay. Just use StateFlow.
⚠️ The Trap: StateFlow for Events
Don’t use StateFlow for events like “Show Toast”. If you emit the same event twice, StateFlow will ignore the second one (because value didn’t change). And if you rotate the screen, the event re-triggers (because it replays).
🏁 Conclusion
- StateFlow: For State (What to show). Replaces LiveData.
- SharedFlow: For Events (What to do). Replaces SingleLiveEvent.
You might also be interested in
Advanced Kotlin Flow: Operators and Patterns
Level up with Kotlin Flow. Master operators like combine, zip, flatMapLatest, and learn to handle complex reactive streams in Android.
Kotlin Coroutines: The Android Guide
Mastering Kotlin Coroutines on Android. Dispatchers, structured concurrency, and best practices for asynchronous programming.
MVVM ViewModel: The Brain of the Operation
Deep dive into the ViewModel component: State management, lifecycle, coroutines, and how to avoid the most common design errors.