Home > OS >  Cannot create instance of MainViewModel - has no zero argument constructor with Compose Hilt
Cannot create instance of MainViewModel - has no zero argument constructor with Compose Hilt

Time:01-20

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

CodePudding user response:

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()
            }
        }
    }

CodePudding user response:

This:

private val mainViewModel: MainViewModel by viewModels()

Needs to be

private val mainViewModel: MainViewModel by hiltViewModel()

This uses Hilt to build your ViewModel, you also need to annotate your activity so that Hilt can inject into it.

@AndroidEntryPoint
class MainActivity
  •  Tags:  
  • Related