Kael Nevarez
Kael Nevarez

Reputation: 53

Cannot create an instance of class view model - Kotlin

I'm currently working on a project to practice dependency injection with Dagger-Hilt, however I can't get my ViewModel to instantiate, I've already looked at some other questions on the same topic, most point the issue to Gradle but that didn't fix it for me, all errors in the Stacktrace are from internal classes except for the 2 lines that involve my ViewModel within the MainActivity

Here is the Stacktrace:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.practiceproject, PID: 9873
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.practiceproject/com.example.practiceproject.ui.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.practiceproject.ui.viewmodel.DogViewModel
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.practiceproject.ui.viewmodel.DogViewModel
    at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
    at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
    at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
    at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:146)
    at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:111)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
    at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
    at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
    at com.example.practiceproject.ui.MainActivity.getDogViewModel(MainActivity.kt:15)
    at com.example.practiceproject.ui.MainActivity.onCreate(MainActivity.kt:22)
    at android.app.Activity.performCreate(Activity.java:7802)
    at android.app.Activity.performCreate(Activity.java:7791)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:214) 
    at android.app.ActivityThread.main(ActivityThread.java:7356) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
 Caused by: java.lang.InstantiationException: java.lang.Class<com.example.practiceproject.ui.viewmodel.DogViewModel> has no zero argument constructor
    at java.lang.Class.newInstance(Native Method)
    at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
    at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278) 
    at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112) 
    at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:146) 
    at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:111) 
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187) 
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
    at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54) 
    at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41) 
    at com.example.practiceproject.ui.MainActivity.getDogViewModel(MainActivity.kt:15) 
    at com.example.practiceproject.ui.MainActivity.onCreate(MainActivity.kt:22) 
    at android.app.Activity.performCreate(Activity.java:7802) 
    at android.app.Activity.performCreate(Activity.java:7791) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:214) 
    at android.app.ActivityThread.main(ActivityThread.java:7356) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

Here is the ViewModel:

class DogViewModel @Inject constructor(
private val getDefaultImages: GetDefaultImages
) : ViewModel() {

val dogModel = MutableLiveData<DogModel>()
val isLoading = MutableLiveData<Boolean>()

fun onCreate() {
    viewModelScope.launch {
        isLoading.value = true
        val result = getDefaultImages()
        if(!result.isNullOrEmpty()) {
            dogModel.value = result[0]
            isLoading.value = false
        }
    }
}

And this is where I'm declaring it:

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding

private val dogViewModel: DogViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    dogViewModel.onCreate()

    dogViewModel.dogModel.observe(this) {
        initRecyclerView(it)
    }
}

Upvotes: 5

Views: 13239

Answers (3)

Bharat Lalwani
Bharat Lalwani

Reputation: 1520

  1. Make sure you have written @AndroidEntryPoint above your Fragment or Activity class.
  2. You have to write @HiltViewModel above your ViewModel Class.
  3. Also make sure you are providing all the dependencies written in ViewModel like repositories, etc.

Upvotes: 5

j2Milad7
j2Milad7

Reputation: 191

You should add @HiltViewModel annotation on top of your view model.

Upvotes: 15

Sergio
Sergio

Reputation: 30645

If don't use getDefaultImages object in DogViewModel you can remove it and it will work. If you use it you need to pass an instance of GetDefaultImages class to the DogViewModel using ViewModelProvider.Factory:

@Suppress("UNCHECKED_CAST")
private val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return DogViewModel(GetDefaultImages()) as T
    }

}

private val dogViewModel: MyViewModel by viewModels { factory }

Upvotes: 1

Related Questions