Android ViewModel with Variable Arguments

Tonny
2 min readApr 30, 2020

Sometime we have to write ViewModel with argument of Int, String, or other type. And copy paste method always came to my mind first. So it will become as following code, obviously on redundancy.

We may find a better solution with generic, reflection andmodel.getConstuctor to retrieve the right constructor and then create the instance.

class AndroidViewModelFactory<P : Any>(
private val application: Application,
private val parameter: P
) : ViewModelProvider.NewInstanceFactory() {
... modelClass.getConstructor(
Application::class.java,
parameter::class.java
).newInstance(application, parameter)

But we have to considerate the difference of reflection in java and kotlin, e.g. 0::class.java return java.lang.Integer, but the constructor need kotlin Int. The simplest way is providing the kotlin class for factory.

class AndroidViewModelFactory<P : Any>(
private val application: Application,
private val parameter: P,
private val kotlinClass: Class<P>? = null
) : ViewModelProvider.NewInstanceFactory() {
... modelClass.getConstructor(
Application::class.java,
kotlinClass ?: parameter::class.java
).newInstance(application, parameter)
...AndroidViewModelFactory(applicaiton, 1, Int::class.java)

But what if in more complicated scenario, there are two, three or more arguments in constructor? The answer seems to be vararg. And once again, we have to find the right kotlin type for each argument for the right constructor.

After struggling with these mess, I find kotlin.reflect maybe can handle that in concise way without considering any performance issue. The code become simple and straightforward.

Have fun with Android Jetpack.

--

--