'How ViewModel is not get destroyed when activity is rotated

I am curious to know how a ViewModel survives when Activity gets rotated because of that it destroyed and recreated again. Logically If we see then ViewModel gets destroyed if the activity which is responsible to create a ViewModel gets destroyed. And while we rotating the device the Activity is destroying.

How the ViewModel knows that Activity is completely finished so that I can destroy myself? Because onDestroy also being called several times if the device rotated, So how ViewModel's onCleared method triggered when activity completely destroyed?



Solution 1:[1]

ViewModels are lifecycle aware which means that when you create a view model you pass the LifecycleOwner to the VM. This helps the View Model to get the state of the context(Be it activity, fragment etc). This allows the view model to broadcast the changes to its observers only when the state is active.

Refer to the below links for more clarity

https://developer.android.com/topic/libraries/architecture/lifecycle#lco https://codelabs.developers.google.com/codelabs/android-lifecycles/#4

Solution 2:[2]

Theory -> There is a hashmap of type HashMap<String, ViewModel> in ViewModelStore (you can call getViewModelStore() from your activity to get it) which stores the ViewModel state and its used to get existing viewModel in next onCreate, and thats how ViewModel survives configuration change. So ViewModel is destroyed when its clear() method is called and viewModelStore's clear method internally calls viewModel's clear.

To answer your question, there exists an internal check, which avoids this clear method getting called in onDestroy if its because of configuration change.

reference from ComponentActivity source code ->

 getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    // Clear out the available context
                    mContextAwareHelper.clearAvailableContext();
                    // And clear the ViewModelStore
                    if (!isChangingConfigurations()) {
                        getViewModelStore().clear();
                    }
                }
            }
        });

Note the if check of isChangingConfiguration, thats why clear is not called on configuration change

Again from source code isChangingConfigurations()

Returns: If the activity is being torn down in order to be recreated with a new configuration, returns true; else returns false.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anup Lal
Solution 2 shubham chouhan