Manually clearing a ViewModel?

by Richard Le Mesurier   Last Updated December 06, 2018 14:26 PM

With reference to the android.arch.lifecycle.ViewModel class.

ViewModel is scoped to the lifecycle of the UI component it relates to, so in a Fragment-based app, that will be the fragment lifecycle. This is a good thing.

In some cases one wants to share a ViewModel instance between multiple fragments. Specifically I am interested in the case where many screens relate to the same underlying data.

(The docs suggest similar approach when multiple related fragments are displayed on the same screen but this can be worked around by using a single host fragment as per answer below.)

This is discussed in the official ViewModel documentation:

ViewModels can also be used as a communication layer between different Fragments of an Activity. Each Fragment can acquire the ViewModel using the same key via their Activity. This allows communication between Fragments in a de-coupled fashion such that they never need to talk to the other Fragment directly.

In other words, to share information between fragments that represent different screens, the ViewModel should be scoped to the Activity lifecycle (and according to Android docs this can also be used in other shared instances).

Now in the new Jetpack Navigation pattern, it is recommended to use a "One Activity / Many Fragments" architecture. This means that the activity lives for the whole time the app is being used.

i.e. any shared ViewModel instances that are scoped to Activity lifecycle will never be cleared - the memory remains in constant use.

With a view to preserving memory and using as little as required at any point in time, it would be nice to be able to clear shared ViewModel instances when no longer required.

How can one manually clear a ViewModel from it's ViewModelStore or holder fragment?

Answers 2

If you don't want the ViewModel to be scoped to the Activity lifecycle, you can scope it to the parent fragment's lifecycle. So if you want to share an instance of the ViewModel with multiple fragments in a screen, you can layout the fragments such that they all share a common parent fragment. That way when you instantiate the ViewModel you can just do this:

CommonViewModel viewModel = ViewModelProviders.of(getParentFragment()).class(CommonViewModel.class);

Hopefully this helps!

December 06, 2018 14:14 PM

There's nothing wrong with using multiple viewmodels as well. First one could be scoped to the Activity while another one could be scoped to the fragment.

Try to use the Activity scoped Viewmodel only for things that need to be shared. And put as many things as possible in the Fragment Scoped Viewmodel. The Fragment scoped viewmodel will be cleared when the fragment is destroyed. Reducing the overall memory footprint.

December 06, 2018 14:22 PM

Related Questions

Updated August 21, 2018 14:26 PM

Updated March 02, 2019 16:26 PM

Updated November 30, 2017 11:26 AM

Updated March 06, 2019 22:26 PM

Updated March 04, 2019 06:26 AM