ViewModel with ViewModelProvider.Factory : The Creator of ViewModel

Muhammad Saeed
KoderLabs
Published in
4 min readMay 6, 2019

Hi Friends! Today I’d like to describe how ViewModel use with ViewModelProvider.Factory.

Let’s Start

So the question, What is ViewModelProvider.Factory? Lets create our ViewModel implementation without ViewModelProvider.Factory.

MyViewModel.kt

And implementation in activity.

MyActivity.kt

Did anyone notice that when we declare MyViewModel in activity using ViewModelProviders, We didn’t call any MyViewModel constructor. The ViewModelProviders internally manage for us and call our primary constructor of ViewModel and create the instance of ViewModel and give the instance back.

Now let see what happens when we pass argument to the constructor of MyViewModel.

MyViewModel.kt

Now create instance of MyViewModel in activity.

MyActivity.kt

No compile time error! Yeah!!

But wait.

When you run this code you will get RunTimeError, Boom!!! RuntimeException cannot create an instance of MyViewModel.

Now let’s see why this happen. The ViewModelProviders.of() method internally creates default ViewModelProvider.Factory implementation for creating our ViewModel with no argument. So when you add argument in the constructor, the inner implementation of ViewModelProvider.Factory failed to initialize your ViewModel because ViewModelProvider.Factory call the primary constructor for creating the ViewModel’s instance. Image below is the default implementation of ViewModelFactory.

ViewModel Factory inner implementation

If you add argument in constructor you have to create your own implementation of ViewModelProvider.Factory to create your ViewModel instance.

What is ViewModelProvider.Factory?

Implementations of ViewModelProviders.Factory interface are responsible to instantiate ViewModels. That means you write your own implementation for creating an instance of ViewModel.

Lets create our own implementation of ViewModelProvider.Factory as below:

MyViewModelFactory.kt

Here is some points to remember.

  1. You pass your ViewModel arguments to the ViewModelProvider.Factory through constructor or any other pattern you prefer (Singleton, FactoryPattern etc.). And it is because you cannot call ViewModel constructor in Activity or Fragment when you initializing ViewModel and you want to set ViewModel constructor’s argument value so that’s why you need to pass argument value to ViewModelProvider.Factory and it will create your ViewModel.
  2. ViewModelProvider.Factory is an interface which have create method. The create method is responsible for creating our VeiwModel’s instance.
  3. The modelClass.getConstructor(Int::class.java) get the constructor which has type Int and create an instance of ViewModel by calling newInstance method and pass constructor values to this method.

Now, lets create our ViewModel instance using ViewModelProvider.Factory in our Activity.

MyActivity.kt

We pass our arguments or dependencies to our ViewModelProvider.Factory so it will manage to create ViewModel for us. The ViewModelProviders.of( context, instanceOfViewModelFactory) method gets the instance of our ViewModelProvider.Factory and now we are responsible to our ViewModel instance process. Just like we do in this example.

So Why we need ViewModelProvider.Factory?

Here some questions comes on mind, I will not passing value to constructor of ViewModel, I will create method to set my values and it will work fine so why need this ViewModelProvider.Factory. In somehow you are right but some cases you need ViewModelProver.Factory.

When to use ViewModelProvider.Factory?

If your ViewModel have dependencies then you should pass this dependencies through the constructor (It is the best way to pass your dependencies), so you can mock that dependencies and test your ViewModel.

When not to use ViewModelProvider.Factory

If your ViewModel have no dependencies then you will not require to create your own ViewModelProvider.Factory. The default implementation is enough to create ViewModel for you.

Conclusion

ViewModelProvider.Factory is responsible to create your instance of ViewModel. If your ViewModel have dependencies and you want to test your ViewModel then you should create your own ViewModelProvider.Factory and passed dependency through ViewModel constructor and give value to the ViewModelProvider.Factory instance.

You can find me on LinkedIn

https://www.linkedin.com/in/muhammad-saeed-younus

--

--