ViewModel & UI State Flashcards

ARCHITECTURE › Components

What does a ViewModel survive, and what does it NOT survive?
It survives configuration changes (rotation, locale, theme, multi-window) because it is retained across the recreation of its ViewModelStoreOwner. It does not survive system-initiated process death; use SavedStateHandle for that.
Why must a ViewModel never hold a reference to a View, Activity, or Context?
A ViewModel can outlive the Activity/Fragment that created it (across config changes), so holding UI references leaks the destroyed instance. Inject dependencies (repositories) instead, and use Application context via APPLICATION_KEY if a context is truly needed.
What is viewModelScope and what happens to it when the ViewModel is cleared?
A CoroutineScope tied to the ViewModel's lifecycle (Dispatchers.Main.immediate + SupervisorJob). When onCleared() runs, the scope is cancelled, automatically cancelling all coroutines launched in it so they don't leak or outlive the ViewModel.
How should a ViewModel expose UI state to the UI, and why?
Keep a private MutableStateFlow and expose a read-only StateFlow via asStateFlow(). This enforces unidirectional data flow: the UI can only read/collect state, never mutate it directly. Compose collects with collectAsStateWithLifecycle().
What is SavedStateHandle and what does it survive that a plain ViewModel does not?
A key-value handle injected into the ViewModel constructor that persists state to a saved-state Bundle. It survives system-initiated process death (low-memory kill while backgrounded), which a plain in-memory ViewModel cannot. Values must be Bundle-compatible (Parcelable/Serializable).
When do you need a ViewModelProvider.Factory, and when do you NOT?
You need a factory when the ViewModel constructor takes dependencies the framework can't supply. You do NOT need one if it has no constructor args, depends only on SavedStateHandle, or uses @HiltViewModel (Hilt generates the factory).
How does the viewModelFactory DSL provide dependencies?
viewModelFactory { initializer { ... } } returns a ViewModelProvider.Factory. Inside initializer you read CreationExtras: APPLICATION_KEY for the Application, createSavedStateHandle() for a SavedStateHandle, or custom CreationExtras.Key entries, then construct and return the ViewModel.
What does hiltViewModel() do and what does it require?
It obtains a Hilt-injected ViewModel scoped to the current ViewModelStoreOwner (NavBackStackEntry or @AndroidEntryPoint host). The ViewModel must be annotated @HiltViewModel with an @Inject constructor; Hilt generates the factory, so you don't write one or pass dependencies manually.
SavedStateHandle vs rememberSaveable vs ViewModel: when to use each?
ViewModel: in-memory state surviving config changes. SavedStateHandle: small ViewModel state surviving process death (queries, IDs, selections). rememberSaveable: UI-only Composable state (scroll, expanded) that survives recreation. Large/complex data belongs in Room or DataStore, not saved state.

Back to ViewModel & UI State