Internals of Android Architecture Components Part I — The ViewModel

Josep Rodriguez
May 20, 2018 · 5 min read
  1. LiveData

Why should we understand how AAC works?

First of all, let’s cover the motivation for this series. I consider best practice to decouple the logic of your application from the platform it runs upon (see Ports and Adapters), that involves decoupling it from any API it may consume, the storage solutions (SQLite, Realm, SharedPreferences, the file system,…), and more importantly, the Android runtime.

  1. The platform dependencies will evolve over time, outside of your control. A change on these dependencies, should not imply a change on your business logic. This is driven by the Single Responsibility Principle (a class should have a single reason to change), and the Stable Dependencies Principle (a package should depend on packages less likely to change than itself).

What are the AAC ViewModels?

On Android’s documentation page it states that ViewModels can be used to keep …

“Store UI-related data that isn’t destroyed on app rotations.”

But how does it manage to do so? Let’s reveal the magic tricks.

How AAC ViewModels are retained across configuration changes

First, let’s visit the Android documentation to see how the ViewModel is consumed. The following code is the example of how a Fragment uses the SDK in order to provide a ViewModel that is retained on configuration changes:

ViewModelProviders.of(this).get(MyViewModel.class);

we can infer that it’s retrieving a ViewModel of type MyViewModel. Let’s look into how each of these methods work, starting with ViewModelProviders.of:

The ViewModelStore

If we look into the dependencies, the ViewModelStore seems to be a simple store with a HashMap<String, ViewModel>, where the key is the classname of the view model and the Object the ViewModel itself:

ViewModelFactory

On the other hand, the ViewModelFactory is using reflection to instantiate the ViewModel we need. The AndroidViewModelFactory used in ViewModelProviders.of overrides a generic ViewModelFactory in order to provide a reference to the Application Context to the ViewModel:

How it all ties together

Now that we understand the ViewModelProvider creation and its dependencies, we will look into how it creates and retrieves theViewModel instances, retaining them throughout configuration changes. Let’s look into the get(MyViewModel.class) method call.

Surviving configuration changes

So far we’ve seen how the ViewModelStore is the object responsible to keep the references of ViewModel to be reused, but how is the ViewModelStore surviving configuration changes itself? Let’s go back to the implementation of ViewModelProviders.of:

  • Implementing ViewModelStoreOwner in our Fragment, and owning the responsibility of creating and disposing the store.
  • Let AAC create a HolderFragment, who already implements ViewModelStoreOwner, and the AAC library and Android SDK will do the heavy lifting.

How HolderFragment retains the state

This raises the question of what is a HolderFragment and how it maps to our Fragment stack. Let’s look now at how holderFragmentFor(Fragment) works:

How android.support.v4.app.Fragment retains state

On the other hand, if you opt for using the support Fragment, the state will be retained, however it becomes more complex to follow the code that manages it.

Isn’t Android’s code “beautiful”?

Summary

To summarise, the reasons it is able to create and retain the ViewModel are:

  1. A ViewModelProvider retains the ViewModel across configuration changes with a ViewModelStore, provided by a ViewModelStoreOwner, this can be done with a HolderFragment, leveraging android.support.v4.app.Fragment or implementing our own.
  2. An android.support.v4.app.Fragment will use the FragmentManager.saveAllState as called by FragmentActivity.onSaveInstanceState to retain the ViewModelStore using theflag mStateSaved on onDestroy.
  3. A HolderFragment is a headless Fragment (without UI) that is added to the Fragment stack with setRetainInstance(true).

References

Other sources that go into more depth onto how AAC works in depth are:

The Lair

Tigerspike's way of exploring how technology and design can benefit humans.

Josep Rodriguez

Written by

Mobile Tech Lead @ Tigerspike

The Lair

The Lair

Tigerspike's way of exploring how technology and design can benefit humans.