Deep dive into ViewModels | In-depth Knowledge

Puneet Grover
4 min readSep 27, 2020

Learn ViewModel Confusing terms and how it works internally/Survives configuration state

What is ViewModel?

The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.

I am not going to explain all the theoretical stuff — for that you can visit -

https://developer.android.com/topic/libraries/architecture/viewmodel#lifecycle

But Yes We will learn the most important things about ViewModel with What does It’s definition means, What problem it Actually Solves?, What’re the questions usually asked about ViewModels

To just Reiterate, I hope you’re aware that when an activity is rotated it gets destroyed and creates again — and we can save the data we want to retain with onSavedInstanceState() method — right?

Now how ViewModel will help here ?

3 Problems 1 Solution — ViewModel

One is Above given approach is only suitable for small amounts of data that can be serialized then deserialized, not for potentially large amounts of data like a list of users or bitmaps.

Second is Memory Leaks — Async Task, Remember ? UI controllers frequently need to make asynchronous calls that may take some time to return. The UI controller needs to manage these calls and ensure the system cleans them up after it’s destroyed to avoid potential memory leaks

Third is UI controllers to also be responsible for loading data from a database or network adds bloat to the class

Just because we are allowed to write everything in a single class / or activity But that doesn’t mean we will — Don’t, I Repeat Don’t do that 💁

Assigning excessive responsibility to the UI controllers in this way also makes testing a lot harder

First, Let’s have a look at ViewModel Lifecycle

Please Read ViewModel Definition once again

“Designed to store and manage UI-related data in a lifecycle conscious way”

“Allows data to survive configuration changes such as screen rotations.”

Now how will the data/ UI state is saved in ViewModel if activity gets rotated?

Let’s read these Interview Question Answers first:-

Are ViewModels independent of activity/fragment lifecycles or just their configuration changes?

ViewModels (VMs) are independent of configuration changes and are cleared when activity/fragment is destroyed.

ViewModel LifeCycle:-

https://developer.android.com/topic/libraries/architecture/viewmodel#lifecycle

How is a ViewModel figuring out internally the right time to call onCleared and finally end its lifecycle?

— > A VM’s onCleared is called when the app is put into the background and the app process is killed in order to free up the system’s memory.

Can the viewModel be shared with another Activity ?

— > You shouldn’t do that with Activities. However fragments can share a ViewModel using their activity scope to handle communication between them

Now again how will the data/ UI state is saved in ViewModel if activity gets rotated?

You may have noticed how we create ViewModel in actual

LoginViewModel model = ViewModelProvider(this).get(LoginViewModel::class.java)

That means we are not creating it like we do for other classes with new keyword — we’re using Abstract Factory pattern here to get the instance of ViewModel

Behind the Scenes and Most asked Interview Question

A HolderFragment is added behind the scenes for the activity if it hasn’t been previously added already. The activity’s HolderFragment is retrieved to get the associated ViewModelStore corresponding to the Activity. Now we know that a HolderFragment has a ViewModelStore, and ViewModelStores store our configuration surviving ViewModels. The HolderFragment is how the ViewModels retain their instance.

public HolderFragment() {

setRetainInstance(true);

}

setRetainInstance(true) is the method behind how the HolderFragment and all the ViewModels inside the ViewModelStore the fragment contains, retains its instance between configuration changes.

when activity recreate, the fragment’s onDestroy() will not be invoked, because of this thing.

I hope you got this particular thing, If not Read it Once again because this is the most important part most people miss. Don’t take a Chance and Cheers 🥂

Now last But not Least I would like to share is:-

What if I want to pass some arguments in constructor of ViewModel, how?

Answer is — ViewModelProvider.Factory

No worries Let’s do it 🤘

See Previously we used this to get instance of ViewModel without arguments

ViewModelProvider(this).get(LoginViewModel::class.java)

But if you have an argument you need to pass to the constructor of the ViewModel, then you need ViewModelFactory. If you try the above approach without the factory, then it results in a compile-time error. 😑

ViewModelProvider.Factory is an implementation of the factory interface that’s responsible for instantiating ViewModels. We need to create our own factory to create ViewModel instances with arguments

The simplest way of doing this is to create our own custom factory-extending ViewModelProvider.Factory interface, which gives an overridden method, create, which is responsible for creating our ViewModel’s instance.

class LoginViewModelFactory (val arg: String): ViewModelProvider.Factory {override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return modelClass.getConstructor(String::class.java).newInstance(arg)
}
}

Now let’s check the implementation inside the activity.

class MainActivity : AppCompatActivity() {lateinit var viewModel: SampleViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val factory = LoginViewModelFactory(“sample”)viewModel = ViewModelProvider(this,factory).get(SampleViewModel::class.java)}}

And It’s Done! 😍

I hope you enjoyed it and Show your love by giving Many many Claps on this Article 🤓

Don’t Forget to Share with your Fellow Developers

Subscribe to My Youtube Channel (CodingWithPuneet) for more such Videos! 🤩

Learn MVVM in Android by CodingWithPuneet

Happy Coding!

Also, Let’s become friends on Linkedin, and Medium

--

--

Puneet Grover

Android Team Lead (Senior Consultant) @Deloitte USI | Google Certified Android Dev | Java | Kotlin | Blogger | Sometimes Youtuber