Cannot create instance of MainViewModel - has no zero argument constructor with Compose Hilt
Using Jetpack Compose to build small Room database app. I keep getting error:
Cannot create an instance of class com.learning.kotlinreadexstingroomdb.MainViewModel
...
Caused by: java.lang.InstantiationException: java.lang.Class<com.learning.kotlinreadexstingroomdb.MainViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
MainActivity.kt
package com.learning.kotlinreadexstingroomdb
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import com.learning.kotlinreadexstingroomdb.ui.theme.KotlinReadExstingRoomDBTheme
class MainActivity : ComponentActivity() {
private val mainViewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
KotlinReadExstingRoomDBTheme {
MyApp()
}
}
}
@Composable
fun MyApp() {
val result by mainViewModel.readAll.collectAsState(initial= emptyList())
Column(
modifier = androidx.compose.ui.Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
if (result.isNotEmpty()) {
Text(
//text = person.name,
text = "There is Data!",
fontSize = MaterialTheme.typography.h4.fontSize
)
} else {
Text(
text = "Empty Database",
fontSize = MaterialTheme.typography.h4.fontSize
)
}
}
}
}
MainViewModel.kt
package com.learning.kotlinreadexstingroomdb
import androidx.lifecycle.ViewModel
import com.learning.kotlinreadexstingroomdb.data.PersonRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
@HiltViewModel
class MainViewModel
@Inject
constructor(personRepository: PersonRepository): ViewModel(){
val readAll = personRepository.readAll
}
build.gradle (:app)
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
...
dependencies {
def room_version = "2.4.1"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
def dagger_hilt_version = "2.40.5"
implementation "com.google.dagger:hilt-android:$dagger_hilt_version"
kapt "com.google.dagger:hilt-compiler:$dagger_hilt_version"
def compose_version = "1.0.5"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.activity:activity-compose:1.4.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
}
I feel like I've tried everything I could find on the web, but nothing fixes it.
Note: Code is based on: Pre-Populate ROOM Database with Already Loaded Data | Android Studio Tutorial
Add @AndroidEntryPoint
annotation in main activity
@AndroidEntryPoint // this line
class MainActivity : ComponentActivity() {
private val mainViewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
KotlinReadExstingRoomDBTheme {
MyApp()
}
}
}
Make sure you annotate your Application class to initialise Hilt
@HiltAndroidApp
class App : Application()
Your Application class needs to be registered in the manifest if it isn't already.
<application
android:name=".App"
... />
You also need to annotate your activities and fragments so that Hilt can inject into them.
@AndroidEntryPoint
class MainActivity