How does ViewModel survive configuration changes, and what actually happens during process death?
The question separates candidates who've only seen rotation survive from those who understand that process death destroys the ViewModel entirely and relies on a completely different mechanism to recover.
LEARN BY DOINGPut your intuition to work3 steps
How does ViewModel survive configuration changes, and what actually happens during process death?
Use the lesson’s examples and explanation to check your idea.
Personal reflection. Nothing is sent to an AI service.#The question behind the question
"How does ViewModel survive rotation?" sounds like a simple lifecycle trivia question, but the answer that actually distinguishes a senior candidate is the one that refuses to treat "configuration change" and "process death" as the same event. They are not. One of them the ViewModel survives for free. The other one destroys the ViewModel completely, and the thing that saves you is a completely different mechanism — SavedStateHandle writing into a Bundle that the operating system, not your app, keeps alive. Conflating the two is the single most common mistake candidates make on this question, and it's exactly the kind of bug that reaches production: code that only tests rotation and assumes it has covered "state restoration."
#Configuration change: the Activity dies, the ViewModel doesn't
A configuration change — screen rotation, switching light/dark mode, a language change, resizing into multi-window — tells the system that resources like layout and drawables might need to reload, so Android's default response is to destroy and recreate the Activity (or Fragment) entirely. onDestroy() and onCreate() both run. But before the old Activity is destroyed, the framework calls a retained, internal hook (historically onRetainNonConfigurationInstance(), now wrapped by ViewModelStore machinery) that hands the ViewModelStore — and every ViewModel inside it — to the new Activity instance instead of discarding it. Nothing in the ViewModel is serialized, nothing is written to disk; it is the literal same object in memory, held alive by a reference the framework quietly threads through the recreation. That's why a StateFlow mid-network-call, or a list you already loaded, is simply still there when the new Activity subscribes to it — there was never a gap.
#Process death: everything actually dies
Process death is a different event entirely. When your app is backgrounded and the system needs memory, it can kill the entire process outright — not just the Activity, the process, including every object in the heap. The ViewModelStore is gone. Every ViewModel instance is gone. There is nothing left in memory to "resume." When the user later returns to your app (via the Recents screen, say), Android starts a brand-new process, and the framework recreates the Activity as though this were a normal cold start — except it hands onCreate() a Bundle it had been holding onto, produced earlier by onSaveInstanceState(), right before the Activity was killed. Everything you get back after process death comes through that Bundle. Everything else — anything only held in a live object graph — is gone and has to be reloaded from a real source of truth: a database, a network call, disk.
#Where SavedStateHandle fits
SavedStateHandle is the bridge that lets a ViewModel participate in that Bundle mechanism without the ViewModel itself needing to know about onSaveInstanceState or Bundle at all. When you request a ViewModel via by viewModels(), Jetpack wires in a SavedStateHandle (via SavedStateViewModelFactory) that is automatically populated from the restored Bundle if the process was killed, or empty if this is a genuine first launch. You read and write to it like a Map-plus-Flow — savedStateHandle.getStateFlow("query", "") — and whatever you put there gets folded into the same Bundle the system saves on your behalf. Crucially, this is the only one of the two survival mechanisms that matters for process death: a plain field on the ViewModel is gone after process death, but a value read from SavedStateHandle comes back.
#Why you can't just put everything in SavedStateHandle
The Bundle backing SavedStateHandle is transported through Android's Binder IPC mechanism to be handed to the ActivityManager process, and Binder transactions share a small buffer across the whole process — commonly cited around 1MB, though the real limit is per-process and not officially documented as a fixed number. Put a large list, a bitmap, or anything non-trivial into a SavedStateHandle and you risk a TransactionTooLargeException that can crash the app on onSaveInstanceState, sometimes only on specific devices or Android versions, which makes it a nasty bug to catch in testing. The rule that keeps you safe: SavedStateHandle is for small, Parcelable-or-primitive pieces of transient UI state — a search query, a selected tab index, a scroll position, an in-progress form field — never for the actual data set. The data set belongs in a database or cache and gets reloaded, not restored byte-for-byte.
#User-initiated exit doesn't get you a Bundle at all
One more distinction worth having ready: if the user presses Back until the Activity legitimately finishes, or swipes it away from Recents, Android does not treat that as a candidate for restoration — there is no saved Bundle to bring back, because the app is not expected to resume where it left off; it's expected to start fresh. The Bundle-and-restore path is specifically for the system reclaiming memory behind the user's back, while the user still expects to return to the same place they left. That expectation is the entire reason the mechanism exists.
🧠 Check your understanding
0/3 · 0/3 answered1. During a configuration change (e.g., screen rotation), what happens to the ViewModel instance?
2. What is destroyed during process death that survives a plain configuration change?
3. Why shouldn't you store a large list of fetched items directly in SavedStateHandle?