Tutorials

    Android ViewModel Internals: Survive Configuration chages

    A
    AzeemJul 8, 2026 · 5 min read
    170

    How ViewModel Survives Configuration Changes in Android - Internal

    When building Android apps using Android Jetpack, one of the most important components is the ViewModel. It helps maintain UI-related data across configuration changes such as device rotation.

    But the real question is:

    How does a ViewModel actually survive when an Activity or Fragment is destroyed and recreated?

    To understand this, we need to explore:

    • ViewModelStore

    • ViewModelProvider

    • ComponentActivity internals

    • NonConfigurationInstance retention in the Android framework

    Let's break it down step-by-step.

    1. The Problem: Configuration Changes

    In Android, when the device rotates or another configuration change occurs, the Android Activity is destroyed and recreated.

    Lifecycle flow during rotation:

    onPause()
    onStop()
    onDestroy()
    code

    Then a new Activity instance is created:

    onCreate()
    onStart()
    onResume()
    code

    If data were stored directly inside the Activity, it would be lost.

    Example:

    var userList = mutableListOf<User>()
    kotlin

    After rotation:

    userList → lost
    API call → triggered again
    UI → reloaded again
    code

    This is the problem ViewModel solves.

    2. The Core Idea of ViewModel

    A ViewModel stores UI-related data outside the Activity/Fragment lifecycle.

    Instead of storing data in the Activity:

    Activity → ViewModel → Data
    code

    Even if the Activity is recreated, the ViewModel instance can still be reused.

    But where is this ViewModel stored?

    That’s where ViewModelStore comes in.

    3. ViewModelStore

    ViewModelStore is a container that holds ViewModel instances.

    Simplified structure:

    public class ViewModelStore {
        private final HashMap<String, ViewModel> mMap = new HashMap<>();
    
        void put(String key, ViewModel viewModel) {
            mMap.put(key, viewModel);
        }
    
        ViewModel get(String key) {
            return mMap.get(key);
        }
    
        void clear() {
            for (ViewModel vm : mMap.values()) {
                vm.clear(); // triggers onCleared()
            }
            mMap.clear();
        }
    }
    kotlin

    Internally it works like:

    ViewModelStore
         |
         |---- "MainViewModel" → ViewModel instance
    code

    Each Activity or Fragment owns a ViewModelStore.

    4. ViewModelStoreOwner

    Both Activity and Fragment implement:

    ViewModelStoreOwner
    code

    Interface:

    interface ViewModelStoreOwner {
        fun getViewModelStore(): ViewModelStore
    }
    kotlin

    Because of this, we can write:

    ViewModelProvider(this)
    kotlin

    Inside either Activity or Fragment.

    5. ViewModelProvider

    ViewModelProvider is responsible for creating or retrieving a ViewModel from the ViewModelStore.

    Simplified logic:

    class ViewModelProvider {
        fun <T : ViewModel> get(key: String, factory: Factory): T {
            if (store.containsKey(key)) {
                return store.get(key) as T
            } else {
                val vm = factory.create()
                store.put(key, vm)
                return vm
            }
        }
    }
    kotlin

    So when you request a ViewModel:

    ViewModelProvider
         |
    Check ViewModelStore
         |
    If exists → return existing instance
    Else → create new ViewModel
    code

    6. ComponentActivity and ViewModelStore

    AppCompatActivityextends ComponentActivity, which manages the ViewModelStore.

    Key implementation:

    @MainThread
    public ViewModelStore getViewModelStore() {
        if (mViewModelStore == null) {
            NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
    
            if (nc != null) {
                mViewModelStore = nc.viewModelStore;
            } else {
                mViewModelStore = new ViewModelStore();
            }
        }
        return mViewModelStore;
    }
    
    kotlin

    Important method used here:

    getLastNonConfigurationInstance()
    code

    This method retrieves objects saved across configuration changes.

    7. NonConfigurationInstances

    Android provides a mechanism to retain objects across configuration changes.

    This is done through an internal container called:

    NonConfigurationInstances
    
    code

    Structure:

    NonConfigurationInstances
         |
         |--- ViewModelStore
         |--- other retained objects
    
    code

    Before the Activity is destroyed, Android calls:

    onRetainNonConfigurationInstance()
    code

    ComponentActivity overrides this method.

    8. onRetainNonConfigurationInstance()

    Implementation:

    @Override
    public Object onRetainNonConfigurationInstance() {
        NonConfigurationInstances nci = new NonConfigurationInstances();
        nci.viewModelStore = mViewModelStore;
        return nci;
    }
    kotlin

    This method returns an object that Android temporarily stores in memory.

    So before destruction:

    Activity
       |
       |--- ViewModelStore
    code

    Becomes:

    NonConfigurationInstances
          |
          |--- ViewModelStore
    code

    This object is saved by the framework.

    9. Framework Internals

    Inside the Android framework, this retention happens through:

    ActivityThread
    code

    Internal flow:

    ActivityThread
         |
    performDestroyActivity()
         |
    retainNonConfigurationInstances()
         |
    NonConfigurationInstances saved
    code

    Then when the new Activity is created:

    ActivityThread.performLaunchActivity()
    code

    The previously saved instance is attached to the new Activity:

    newActivity.mLastNonConfigurationInstances = oldInstance
    code

    10. Activity Recreation Flow

    Full lifecycle during rotation:

    Activity A created
          |
    ViewModelStore created
          |
    User rotates screen
          |
    onRetainNonConfigurationInstance()
          |
    ViewModelStore saved
          |
    Activity A destroyed
          |
    Activity B created
          |
    getLastNonConfigurationInstance()
          |
    ViewModelStore restored
          |
    ViewModelProvider returns same ViewModel
    
    code

    So the ViewModel instance never gets destroyed during rotation.

    11. When ViewModel Is Actually Destroyed

    ViewModel survives configuration changes only.

    But if the Activity finishes permanently:

    User presses back
    Activity finished
    code

    Then:

    ViewModelStore.clear()
    code

    Which triggers:

    ViewModel.onCleared()
    code

    Example:

    override fun onCleared() {
        super.onCleared()
    }
    kotlin

    Used for:

    • cancelling coroutines

    • closing resources

    • removing listeners

    12. Process Death Case

    If the system kills the app due to low memory:

    Process killed
    Memory cleared
    ViewModelStore lost
    code

    Nothing survives.

    This is why we use:

    • SavedStateHandle

    • database

    • datastore

    for persistent state.

    13. Fragment ViewModel Behavior

    Fragments also support ViewModel.

    Two common scopes:

    Fragment Scope

    Fragment → ViewModel
    code

    Destroyed when fragment is removed.

    Activity Scope

    Activity
       |
       |--- Shared ViewModel
            |
            |--- Fragment A
            |--- Fragment B
    code

    Fragments share the same ViewModel instance.

    Visual Flow

    Old Activity
         |
         |---- ViewModelStore
                 |
                 |---- ViewModel
    
    ↓ Rotation
    
    New Activity
         |
         |---- Reuses ViewModelStore
                 |
                 |---- Same ViewModel instance
    
    code

    Interview Summary

    How does ViewModel survive configuration changes?

    Answer:

    ViewModel survives configuration changes because it is stored inside a ViewModelStore owned by the Activity or Fragment. During configuration changes, the system calls onRetainNonConfigurationInstance() and saves the ViewModelStore inside a NonConfigurationInstances object. When the Activity is recreated, the previously retained ViewModelStore is restored and reused by ViewModelProvider, which returns the same ViewModel instance.

    ActivityThread
     → performDestroyActivity
     → retainNonConfigurationInstances
     → NonConfigurationInstances
     → ViewModelStore
     → ViewModelProvider
    
    code

    Was this helpful?

    Comments (0)

    No comments yet. Be the first to share your thoughts!

    Leave a Comment

    Get the latest updates

    Join our newsletter and never miss an article.

    By subscribing, you agree to our Privacy Policy and consent to receive updates.

    Ready to Start Learning?

    Join thousands of students building their dream careers

    Explore Courses