π‘ Everything You Need to Know About SharedFlow in Android
π’ Everything You Need to Know About SharedFlow in Android
As modern Android development evolves, reactive and coroutine-based architectures are taking center stage. While LiveData
and StateFlow
are great for observing state, SharedFlow
is the go-to solution for one-time events, like showing a toast, navigation, or triggering dialogs.
In this post, weβll explore:
- What is SharedFlow?
- SharedFlow vs StateFlow vs LiveData
- Use cases for SharedFlow
- How SharedFlow works
- Code examples
- Best practices
- Common pitfalls
π‘ What is SharedFlow?
SharedFlow
is a hot flow introduced in Kotlin Coroutines 1.4.0+ as part of the kotlinx.coroutines.flow
package. Unlike StateFlow
, which holds and replays the latest value, SharedFlow
can emit multiple values and can be configured to replay a specific number of past values to new collectors.
Think of
SharedFlow
as a coroutine-based event broadcasterβsuitable for one-time events like navigation, snackbars, or messages.
π SharedFlow vs StateFlow vs LiveData
Feature | SharedFlow | StateFlow | LiveData |
---|---|---|---|
Lifecycle aware | β No | β No | β Yes |
Holds latest value | β Optional | β Always | β Yes |
Supports multiple collectors | β Yes | β Yes | β οΈ Limited |
Replay values | β Customizable | β Only latest | β οΈ No |
Event support | β Ideal for events | β Avoid for one-time events | β οΈ Workarounds needed |
Coroutine-native | β Yes | β Yes | β οΈ Optional |
π Why Use SharedFlow?
- π₯ Hot stream β always emits even if no one is collecting.
- π§΅ Coroutine-native β works well with
viewModelScope
andlifecycleScope
. - π€ Supports multiple collectors β great for broadcasting.
- βͺ Replay support β can replay past values to new collectors.
- π― Best suited for one-off events β like toasts, navigation, and UI signals.
𧬠Anatomy of SharedFlow
SharedFlow is read-only by default, but you use MutableSharedFlow
to emit values.
ViewModel setup:
```kotlin
class MyViewModel : ViewModel() {
private val _events = MutableSharedFlow
1
2
3
4
5
6
7
8
fun sendEvent(message: String) {
viewModelScope.launch {
_events.emit(message)
}
} } Collect in Activity or Fragment: kotlin Copy Edit lifecycleScope.launchWhenStarted {
viewModel.events.collect { event ->
Toast.makeText(context, event, Toast.LENGTH_SHORT).show()
} } βοΈ SharedFlow Configuration MutableSharedFlow can be customized using:
kotlin
Copy
Edit
MutableSharedFlow
kotlin
Copy
Edit
val messages = MutableSharedFlow
π One-time messages like snackbars/toasts
β Form submission success
β Error reporting
πΉοΈ UI triggers (dialogs, modals)
π§ Real-world Example: Navigation kotlin Copy Edit sealed class UiEvent { data object NavigateToHome : UiEvent() data class ShowToast(val message: String) : UiEvent() }
class MyViewModel : ViewModel() {
private val _uiEvent = MutableSharedFlow
1
2
3
4
5
fun onLoginSuccess() {
viewModelScope.launch {
_uiEvent.emit(UiEvent.NavigateToHome)
}
} } Collecting in Activity or Compose:
kotlin Copy Edit lifecycleScope.launchWhenStarted { viewModel.uiEvent.collect { event -> when (event) { is UiEvent.NavigateToHome -> navigateToHome() is UiEvent.ShowToast -> Toast.makeText(context, event.message, Toast.LENGTH_SHORT).show() } } } π Best Practices Always expose SharedFlow as read-only using .asSharedFlow().
Use viewModelScope.launch to emit values safely.
Avoid replaying large values unless necessary.
Prefer SharedFlow over LiveData
In Jetpack Compose, remember to collect inside LaunchedEffect or rememberCoroutineScope.
β Common Pitfalls
Pitfall Solution No collectors? Emit is suspended. Use extraBufferCapacity > 0 or tryEmit() Multiple toasts/events firing again Set replay = 0 Using for UI state Prefer StateFlow instead Lifecycle issues Collect in lifecycleScope.launchWhenStarted π§ Final Thoughts SharedFlow is a powerful addition to Kotlinβs reactive toolkit and fills a critical gap left by LiveData and StateFlow. Itβs especially useful when you need event-based communication between ViewModel and UI, without worrying about lifecycle.