'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 |