How does a ViewModel survive a configuration change, and what does it not survive that SavedStateHandle is for?
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.
What the interviewer is scoring
- Can the candidate explain the ViewModelStore mechanism rather than saying ViewModel "just survives" rotation
- Do they clearly distinguish a configuration change from process death as two different events with different guarantees
- Whether they know SavedStateHandle is backed by a small bundle with a size limit, not a general persistence mechanism
- Can they name what onCleared() indicates versus what a configuration-change teardown does
- Does the candidate know how to actually test process-death restoration rather than only rotation
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.
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.
sequenceDiagram
participant A1 as Activity instance 1
participant Store as ViewModelStore
participant A2 as Activity instance 2
A1->>Store: request ViewModel (created, cached)
Note over A1: Configuration change - rotation
A1->>A2: Activity destroyed, new instance created
A2->>Store: request ViewModel
Store-->>A2: same instance, state intactonCleared() 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.
class SearchViewModel(
private val savedStateHandle: SavedStateHandle,
private val 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 onQueryChanged(newQuery: String) {
savedStateHandle["query"] = 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.
© 2026 Preptima. Originally published at preptima.com.
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?
Related questions
- How do you choose which devices to test on, and what will an emulator never tell you?mediumAlso on android5 min
- A Compose screen with a long list is janky while scrolling - walk through how you'd find and fix the recomposition problem causing it.mediumAlso on android5 min
- What does structured concurrency actually give you in Kotlin coroutines, and how does a coroutine scope leak happen despite it?mediumAlso on android4 min
- You need to run background work on Android - how do you choose between WorkManager, a foreground service, and AlarmManager?mediumAlso on android4 min