Preface

In this article we will dive deep into ViewModel component. In case you missed the previous article or don’t know about architecture components then head on to my previous article Introduction to Android Architecture Components.

The code in this article is written in Kotlin. In case you don’t know Kotlin. Read this series of article to get started.

Introduction

Screen Rotation

Most of us have faced the issue where we rotate the phone and either the app crashes or the UI looses it’s state.

The easiest solution for it is just fix the Activity to potrait mode and we are done. It’s very bad practice to do so. Lucky for us, Android Team released ViewModel during Google I/O 2017.

The ViewModel class is designed to store the UI related data and this component is lifecycle aware which allows it to survive the configuration change automatically, saving us from the hard stuff.

It has following responsibilities:

  • It’s main responsibility is to manage the data for the UI
  • It handles the communication between Activity / Fragment and rest of the application
  • Retains the data during the configuration change

Note: It should never ever access your view hierarchy or hold a reference back to the Activity or the Fragment.

Adding it to your project

Add the following dependencies in your app or module build.gradle

// For Lifecycle, ViewModel and LiveData
compile “android.arch.lifecycle:runtime:1.0.0-alpha3”
compile “android.arch.lifecycle:extensions:1.0.0-alpha3”
// Java
annotationProcessor “android.arch.lifecycle:compiler:1.0.0-alpha3”
// Kotlin
kapt “android.arch.lifecycle:compiler:1.0.0-alpha3”

Writing your ViewModel class

A simple ViewModel class holds the data and returns the LiveData reference to observe for changes in the data.

Your ViewModel class shouldn’t contain the logic to fetch the data however you can still write in the ViewModel itself for prototyping purpose.

In case you require the context in your ViewModel class then extend AndroidViewModel instead of ViewModel

Get the instance of ViewModel

To get the instance of ViewModel you can use the ViewModelProviders we will look into it’s internals in later below.

PS: Did you notice we have used LifecycleActivity? It is part of the Lifecycle component and it provides the lifecycle which is required by other components to be lifecycle aware. Don’t worry about it much, we will look into it later.
Moreover it will be part of AppCompatActivity once the architecture components become stable.

But, how does ViewModel retain configuration change?

In order to understand that we will look at lifecycle of ViewModel

Lifecycle of ViewModel

ViewModel objects are scoped to the Lifecycle passed to the ViewModelProvider when getting the instance ViewModel in Activity / Fragment. Hence it stays in memory until the scope of Lifecycle goes away permanently—in the case of an activity, when it finishes; in the case of a fragment, when it’s detached.

In a nutshell, ViewModel instance is not destroyed during configuration change and after Activity / Fragment is re-created on configuration change the existing instance is re-attached to the Activity / Fragment

Finally when the owner activity is finished, the Framework automatically calls ViewModel’s onCleared() method so that it can clean up resources.

Under the hood — Internals

We have understood how to write and use ViewModel. Let’s look little bit at it’s internals.

val simpleViewModel = ViewModelProviders.of(this).get(SimpleViewModel::class.java)

ViewModelProviders is an utility class for ViewModelStore. It internally refers to ViewModelStore to return existing instance of ViewModel if exists else create a new one.

ViewModelStore internally keeps track of the ViewModels using a HashMap

Source of ViewModelStore

If you looks closely at ViewModelProviders.of(this) function. You’ll notice that the ViewModels are associated with the UI (Activity/Fragment).

ViewModel vs SavedInstanceState

ViewModel are not persisted if the application is killed by the System. While the data saved using onSavedInstanceState is persisted in System Memory that means the data will be available after app starts again.

That being said, Android system allows only very small amount of data for SavedInstanceState which means it’s not a good place to store your app data.

Read more about it: https://developer.android.com/topic/libraries/architecture/viewmodel.html#viewmodel_vs_savedinstancestate

Conclusion

ViewModels are very useful for seperating your data from the UI which benefits during testing and the fact that it survives configuration changes is one beautiful reason to use ViewModel component in your app. It even cleans itself up is another great factor.

Lastly, it even makes the communication easier between Fragments.

With ViewModels you don’t need to worry about app crash or losing UI state during screen rotation or other configuration change

--

--

Akshay Chordiya
AndroidPub

Google Developer Expert @ Android | Android Engineer @ Clue | Instructor @Caster.IO