I am currently facing an issue with incorporating dependency injection into my app, which I developed using Jetpack Compose.
I have included the following dependencies and plugins for Dagger Hilt:
Project level gradle file:
plugins {
...
id("com.google.dagger.hilt.android") version "2.51.1" apply false
}
Module level gradle file:
plugins {
...
id("kotlin-kapt")
id("com.google.dagger.hilt.android")
}
dependencies {
...
//hilt
implementation(libs.hilt.android)
kapt(libs.hilt.android.compiler)
implementation(libs.androidx.hilt.navigation.compose)
kapt(libs.androidx.hilt.compiler)
implementation(libs.androidx.hilt.navigation.fragment)
}
kapt {
correctErrorTypes = true
}
With this version catalog:
[versions]
agp = "8.5.0"
hiltAndroid = "2.51.1"
hiltAndroidCompiler = "2.48"
hiltLifecycleViewmodel = "1.0.0-alpha03"
hiltNavigationCompose = "1.2.0"
kotlin = "1.9.0"
coreKtx = "1.13.1"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hiltNavigationCompose" }
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
androidx-hilt-navigation-fragment = { module = "androidx.hilt:hilt-navigation-fragment", version.ref = "hiltNavigationCompose" }
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hiltAndroidCompiler" }
#hilt-android-gradle-plugin seems to be greyed out - it isn't being used
hilt-android-gradle-plugin = { module = "com.google.dagger:hilt-android-gradle-plugin", version.ref = "hiltAndroid" }
[plugins]
#No Hilt-Related plugins, only android-application and kotlin
I had created a HiltViewModel, as such:
@HiltViewModel
class GameViewModel @Inject constructor(
private val sample: Sample
) : ViewModel() {
...
}
where Sample is a dummy class which is defined as such:
class Sample (
context: Context
)
The Module for injecting my dependencies and my application class are also included, for reference:
import android.app.Application
import com.example.cheesechase.gyroscope.Sample
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun giveSample(context: Application): Sample {
return Sample(context)
}
}
I've given the @AndroidEntryPoint annotation to my MainActivity class, from where I call the navigation composable (I use Compose Navigation). I Initialise my viewmodel inside the Navigation Composable using
val viewModel = hiltViewModel<GameViewModel>()
and pass it to my screens as the viewModel variable. Now, when I try to run the code, I get the following exception:
java.lang.RuntimeException: Cannot create an instance of class com.example.cheesechase.GameViewModel
at androidx.lifecycle.viewmodel.internal.JvmViewModelProviders.createViewModel(JvmViewModelProviders.kt:40)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.android.kt:193)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.android.kt:317)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.android.kt:299)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.android.kt:273)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.kt:128)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:172)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:172)
at androidx.lifecycle.ViewModelProvider$Factory.create(ViewModelProvider.android.kt:158)
at androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release(ViewModelProviderImpl.kt:67)
at androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release$default(ViewModelProviderImpl.kt:47)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.android.kt:91)
at androidx.lifecycle.viewmodel.compose.ViewModelKt__ViewModelKt.get(ViewModel.kt:162)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(Unknown Source:1)
at androidx.lifecycle.viewmodel.compose.ViewModelKt__ViewModel_androidKt.viewModel(ViewModel.android.kt:124)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(Unknown Source:1)
at com.example.cheesechase.navigation.NavigationKt.Navigation(Navigation.kt:84)
at com.example.cheesechase.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:38)
at com.example.cheesechase.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:36)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:118)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:239)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:221)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:989)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:476)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:90)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3302)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3235)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:723)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1071)
at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3599)
at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:631)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:617)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:499)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:471)
I have tried moving the initialization to the MainActivity, other places too, to no avail. I tried changing and switching up the gradle plugins and dependencies. Also, the code works fine (runs without errors) when I include no dependencies in my GameViewModel constructor, like this:
@HiltViewModel
class GameViewModel @Inject constructor() : ViewModel() {...}