Android ViewModel & State Management
Instructions
Use ViewModel to hold state and business logic. It must outlive configuration changes.
1. UI State (StateFlow)
- •What: Represents the persistent state of the UI (e.g.,
Loading,Success(data),Error). - •Type:
StateFlow<UiState>. - •Initialization: Must have an initial value.
- •Exposure: Expose as a read-only
StateFlowbacking a privateMutableStateFlow.kotlinprivate val _uiState = MutableStateFlow<UiState>(UiState.Loading) val uiState: StateFlow<UiState> = _uiState.asStateFlow()
- •Updates: Update state using
.update { oldState -> ... }for thread safety.
2. One-Off Events (SharedFlow)
- •What: Transient events like "Show Toast", "Navigate to Screen", "Show Snackbar".
- •Type:
SharedFlow<UiEvent>. - •Configuration: Must use
replay = 0to prevent events from re-triggering on screen rotation.kotlinprivate val _uiEvent = MutableSharedFlow<UiEvent>(replay = 0) val uiEvent: SharedFlow<UiEvent> = _uiEvent.asSharedFlow()
- •Sending: Use
.emit(event)(suspend) or.tryEmit(event).
3. Collecting in UI
- •Compose: Use
collectAsStateWithLifecycle()forStateFlow.Forkotlinval state by viewModel.uiState.collectAsStateWithLifecycle()
SharedFlow, useLaunchedEffectwithLocalLifecycleOwner. - •Views (XML): Use
repeatOnLifecycle(Lifecycle.State.STARTED)within a coroutine.
4. Scope
- •Use
viewModelScopefor all coroutines started by the ViewModel. - •Ideally, specific operations should be delegated to UseCases or Repositories.