How does a ViewModel survive a configuration change, and what does it not survive that SavedStateHandle is for?
4 min readUpdated 2026-08-15
0
Answer
Short answer
A ViewModel outlives a configuration change like rotation because the Activity is recreated while the ViewModelStore is retained, but it does not survive process death from memory pressure, which is what SavedStateHandle exists to restore state across.
Keep android explicit in the answer because that is the concept the interviewer is actually trying to test. A good android explanation names the trade-off, the failure mode, and the evidence you would use before choosing.
Was this answer helpful?
Likely follow-ups
→How would you test that your screen restores correctly after system-initiated process death, given that a debugger attached usually prevents it?
→What kind of data belongs in SavedStateHandle versus what belongs in a database or a repository cache?
→Why can't you put a large object like a Bitmap directly into SavedStateHandle?
→What is the practical difference between onCleared() being called and the process being killed without any callback at all?
Two different events that look similar from the UI
Two things can end an Activity's current instance, and they are easy to conflate because both make the screen disappear and reappear: a configuration change, such as rotating the device or changing the system font size, and process death, where the Android system kills the entire app process to reclaim memory while the app is backgrounded. Only the first is something ViewModel was designed to survive on its own; the second requires a separate mechanism, and an interview answer that treats them as one case is missing the actual point of SavedStateHandle.
How ViewModel survives a configuration change
On a configuration change, the Activity instance is destroyed and a new one is created, but the framework retains a ViewModelStore associated with that activity's identity across the transition and hands it to the new Activity instance rather than creating a fresh one. Because the ViewModelStoreOwner (the Activity or Fragment) survives the recreation even though the specific object instance does not, the ViewModel instances inside that store are never torn down - the new Activity instance asks for its ViewModel through the same store and gets back the exact same object, with everything still in memory. This is why in-memory state that a ViewModel holds in a plain property, not just in SavedStateHandle, survives rotation with zero extra code: nothing about the ViewModel was ever destroyed.
Loading diagram…
onCleared() is the signal for the other case - the ViewModel is being destroyed for real, because its owning Activity or Fragment is finishing permanently rather than being recreated for a configuration change. That is where you cancel viewModelScope work and release resources, and it deliberately does not fire on a configuration change, because the whole point of the mechanism is that nothing needs cleaning up in that case.
What process death removes that rotation does not
Process death is a different failure mode entirely: the OS kills the whole process, including every ViewModelStore and every object in memory, with no destructor-style callback guaranteed to run first. When the user later navigates back to the app, Android creates a brand-new process and a brand-new Activity, and every in-memory ViewModel property from before is simply gone - there is no store to hand back, because the process that held it no longer exists. A ViewModel that only relied on surviving in memory across a configuration change offers nothing here, which is the gap SavedStateHandle closes.
SavedStateHandle is a small, framework-managed key-value store that a ViewModel can accept in its constructor. Its contents are serialized into the same Bundle mechanism the OS already uses for onSaveInstanceState, and that bundle is what the OS preserves specifically to support restoring a killed process's UI state, subject to the same size constraints as that bundle - it is meant for small values like a selected id, a scroll position, or a query string, not for caching a list of full objects or anything like an image.
classSearchViewModel(
privateval savedStateHandle: SavedStateHandle,
privateval repository: SearchRepository
) : ViewModel() {
// Restored from the OS-preserved bundle after process death,// not just retained in memory across a configuration change.val query: StateFlow<String> = savedStateHandle.getStateFlow("query", "")
fun {
savedStateHandle[] = newQuery
}
}
Setting a value through savedStateHandle["query"] both updates the in-memory value the ViewModel uses immediately and marks it for inclusion in the saved bundle, so the same line of code covers the rotation case and the process-death case without the developer having to write two separate paths.
Why testing this by rotating the device proves nothing about it
Rotation exercises the ViewModelStore retention path, which is exactly the case that never needed SavedStateHandle in the first place, so a developer who only tests by rotating a device can ship a screen with a SavedStateHandle implementation that has a real bug and never notice. The correct test is to actually force process death - Android Studio's "Kill activity" developer option under the running-devices menu, or adb shell am kill <package> after backgrounding the app, then returning to it - because a debugger attached to a running process generally prevents the OS from killing it under memory pressure the way it would in the field, making the bug invisible in a debugged session even when it is genuinely present.
The trap here is the phrase "ViewModel survives configuration changes," said as though it were the whole story about ViewModel and persistence. It is true and it is also the easy fifteen percent of the problem; the harder and more commonly tested part is recognising that the same phrase says nothing about what happens when the process itself is gone, which is the everyday case for a user who backgrounds an app for twenty minutes on a memory-constrained device.
ViewModel surviving rotation and SavedStateHandle surviving process death are two separate guarantees, solving two separate ways a screen's state can be lost - test each one by causing the specific event it protects against, not by rotating the device and assuming that covers both.