Android ViewModel Recreation: Fixing the Rotation State Trap
Rotation bugs usually appear as “random resets.” The root cause is state living in views instead of a lifecycle-aware model.
Step 1: Move UI state to immutable model snapshots
data class QuizUiState(
val questionIndex: Int = 0,
val selectedAnswer: Int? = null,
val score: Int = 0
)
Step 2: Expose state from ViewModel only
class QuizViewModel : ViewModel() {
private val _state = MutableStateFlow(QuizUiState())
val state: StateFlow<QuizUiState> = _state
}
Step 3: Persist critical fields via SavedStateHandle
handle["questionIndex"] = newIndex
Pitfalls
- Keeping selection state inside composables only.
- Using activity fields as temporary source of truth.
- No rotation test cases in instrumentation suite.
Validation
- Rotate screen mid-quiz and state remains intact.
- Background/foreground cycle preserves progress.
- ViewModel remains single source of truth.