Site icon AndroidRide

5 Ways To Get Instance Of ViewModel In Android

Creating viewmodel instance is needed if you are using MVVM architecture. Otherwise, MVVM is incomplete.  So in this post, I will tell you about different ways for creating instance of ViewModel in activity or fragment.

By using correct usage of viewmodel, we can avoid ‘Android cannot create instance of viewmodel’ issue also.

okay, let’s start.

First I will tell you in short. So it will save your time.

  1. viewModel() – Used in Jetpack Compose.
  2. by viewModels() – Apply it with Activity or fragment.
  3. by activityViewModels() – Recommended to use when multiple fragments need to share same data and has same instance of Activity
  4. Using ViewModelProvider – old way but still works.
  5. using ViewModelProvider.Factory –  Make use of it if you need to pass arguments to viewmodel.
  6. @hiltViewModel – This is from Hilt dependency injection, very helpful if you are using Hilt.
    • hiltViewModel() – Use it in Composables

Below, I have mentioned versions of different dependencies, so if you need different version, please check the maven repository and use the latest one.

Detailed Version With Code

  1. viewModel()

In Jetpack Compose, viewModel() delegate can be used for creating instance of viewmodel. But before that you need to include the dependencies in gradle file, only then you can use this. If you want to pass parameters, then go with Hilt or ViewModelProvider.Factory


androidx.Lifecycle:lifecycle-viewmodel-compose:"latest version"(2.8.7 )

2.  by viewModels()

val viewModel: MyViewModel by viewModels()

If you are using XML based approach, you can easily create instance of viewmodel using viewModels(). This does not support passing parameters.

3. activityViewModels()

val viewModel: MyViewModel by activityViewModels()

You can use this in your fragment to access instance of viewmodel – better to use when multiple fragment within same activity needs viewmodel instance.

implementation("androidx.fragment:fragment-ktx:1.6.2")

4. Use ViewModelProvider

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

As the name suggests ViewModelProvider gives the viewmodel instance by passing class type of the viewmodel.
5. ViewModelProvider.Factory

val repository = MyRepository()
val factory = MyViewModelFactory(repository)
viewmodel = ViewModelProvider(this, factory)[MyViewModel::class.java]

In most cases, we need to pass a repository or other instances to the viewmodel. So in this example, i am passing a repository to the viewmodel using ViewModelProvider.

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider

class MyViewModelFactory(private val repository: MyRepository) :ViewModelProvider.Factory{
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if(modelClass.isAssignableFrom(MyViewModel::class.java)){
         return MyViewModel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }

}

Here, the subclass of ViewModelProvider.Factory will receives the instance of repository and creates viewmodel instance for you.

5. Using @HiltViewModel

This approach can be used if you are Hilt dependency injection in your project. But you need to do some changes here, not easy like above steps,

1. You need to add dependency in gradle file.
2. Define subclass of Application and annotate with @HiltAndroidApp.
3. Annotate viewmodel class with @HiltViewModel.
4. if you want to access instance of viewmodel in activity or fragment, annotate those with @AndroidEntryPoint


  //  id 'com.google.dagger.hilt.android' version '2.48' apply false

   // Dagger - Hilt
    implementation "com.google.dagger:hilt-android:2.48"
    kapt "com.google.dagger:hilt-android-compiler:2.48"
    kapt "androidx.hilt:hilt-compiler:1.0.0"

@HiltAndroidApp
class MyApplication: Application()

@HiltViewModel
class MainViewModel @Inject constructor(
    private val repository: Repository,
    application: MyApplication
): AndroidViewModel(application)

@AndroidEntryPoint
class MyFragment : Fragment() {

    private val mainViewModel: MainViewModel by viewModels()


hiltViewModel() - call in composable if you are using hilt.

This is for now, may be I will update later.
Thanks.

Exit mobile version