Parameterized ViewModelProvider(s)

gizmodo.com

When I thought I’m the first one to experience hard time injecting parameterized ViewModel into Activity/Fragment, stretched my fingers to google and found few places where developers struggled before. Here, here and here.

The Factory

First, we need to consider what are the building component of ViewModelProvider. Let’s discuss the basic constructs, the ViewStore and Factory.

ViewStore is not employed to generate the instances, so we keep it as is. ViewModel.Factory does all object spawning of class extending ViewModel.

NewInstanceFactory is looking for an empty constructor of the provided class in get(Class<T> class). Yes, that’s what we need, a Factory that will generate instance of a class that has parameterized constructor. In his article, Danny Preussler proposed single-purpose Factory for specific type. Let’s escalate it to more generic Factory that dodges single-purpose idea.

Under the hood

It’s simple. ParametrizedFactory takes array of objects that will be provided for constructor invocation of modelClass. When get() method is called, it checks up the size of object array argument passed in the factory constructor. If the array is empty it invokes the empty constructor of the modelClass (if having one), the second case is where we have variable number of arguments.
Factory searches for constructor matching the type classes of object array.

Any mismatch in class type or order in object array will result with exception, probably failing to invoke method (constructor) with incorrect params.

Kotlin tip
When you call Java function that has variable number of arguments (three dots method) use spread operator *.

Don’t

Never ever ever, pass callbacks or Context to ViewModel subclasses’ constructor. (caps lock)

Bonus Java: