2

I am working with Android 14 api, Kotlin 2.0.0 and I'm using Hilt for dependency injection.

What is wrong with my Hilt config that is preventing the creation of the FirstViewModel?

I get the following error:

java.lang.RuntimeException: Cannot create an instance of class 
    ui.viewmodels.FirstViewModel
    ...
  Caused by: java.lang.NoSuchMethodException: 
    ui.viewmodels.FirstViewModel.<init> []
    at java.lang.Class.getConstructor0(Class.java:3325)
    at java.lang.Class.getDeclaredConstructor(Class.java:3063)
    at androidx.lifecycle.viewmodel.internal.JvmViewModelProviders.createViewModel(JvmViewModelProviders.kt:38)

I have added an App class

@HiltAndroidApp
class App: Application()

I have added the App class to the AndroidManifest.xml

<application
    android:name=".App"

My main activity has the @AndroidEntryPoint annotation:

@AndroidEntryPoint
class MainActivity : ComponentActivity() {}

My Hilt module:

@Module
@InstallIn(SingletonComponent::class)
object DataModules {
    @Provides
    @Singleton
    fun providesFirstApi(): FirstApi =
        Retrofit.Builder().baseUrl("http://localhost:3000").addConverterFactory(
            GsonConverterFactory.create()
        ).build().create(FirstApi::class.java)

    @Provides
    @Singleton
    fun provideFirstRepository(firstApi: FirstApi): FirstRepository{
        return FirstRepositoryImpl(firstApi)
    }
}

The view model in question:

@HiltViewModel
class FirstViewModel @Inject constructor(private val firstRepository: FirstRepository): ViewModel() {
   suspend fun getDetails() = firstRepository.getServices()
}

interface FirstRepository{
    suspend fun getServices(): List<MyObject>
}

class FirstRepositoryImpl(private val firstApi: FirstApi): FirstRepository {
    override suspend fun getServices() = listOf(MyObject())
}
import retrofit2.http.GET

interface FirstApi{
    @GET("services")
    suspend fun getServices(): List<MyObject>
}

The composable in which I am trying to inject:

@Composable
fun Details(
    FirstViewModel: FirstViewModel = viewModel()
) {
    // ...
}

The relevant parts of my module level gradle file:

plugins {
    alias(libs.plugins.dagger.hilt.android)
}

dependencies {
    ksp(libs.dagger.compiler)
    ksp(libs.androidx.hilt.compiler)
    implementation(libs.hilt.navigation.compose)
    androidTestImplementation(libs.hilt.android.testing)
    testImplementation(libs.hilt.android.testing)
    implementation(libs.hilt.compiler)
    implementation(libs.hilt.android)
}

The relevant parts of the version catalog:

[versions]
daggerCompiler = "2.48"
hiltCompilerVersion = "1.2.0"
androidxHiltNavigationCompose = "1.2.0"
hiltAndroidTesting = "2.51.1"
hiltCompiler = "2.51.1"
hiltAndroidVersion = "2.44"
daggerHiltAndroid = "2.44"

[libraries]
dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "daggerCompiler" }
androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hiltCompilerVersion" }
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "androidxHiltNavigationCompose" }
hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hiltAndroidTesting" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hiltCompiler" }
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroidVersion" }

[plugins]
dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "daggerHiltAndroid" }
5
  • 2
    Use hiltViewModel instead of viewModel() in your Composable Commented Jun 18, 2024 at 1:56
  • using hiltViewModel crashes with the same error. The adnroid docs state use viewModel() developer.android.com/develop/ui/compose/libraries#hilt Commented Jun 18, 2024 at 11:55
  • Scroll down to the next section, there it says: "When using Navigation Compose, always use the hiltViewModel composable function [...]" Commented Jun 18, 2024 at 12:00
  • switch from ksp to kapt and remove ksp(libs.androidx.hilt.compiler) // "1.2.0". Commented Jun 19, 2024 at 4:16
  • 1
    That's grasping at straws. Why revert to kapt? Instead of guessing we should wait until we have the full picture (i.e. succeed updates the question with the version catalog, as I already asked for three times). Then we can make an informed attempt to answer. All guess work up until then should be minimized. Commented Jun 19, 2024 at 8:03

1 Answer 1

1

You are mixing three different Hilt versions:

  • 2.44: hiltAndroidVersion, daggerHiltAndroid
  • 2.48: daggerCompiler
  • 2.51.1: hiltAndroidTesting, hiltCompiler

The idea of specifying the versions separately is that you can reuse the same version variable for multiple artifacts. Since you always want the same version for all of the above artifacts, remove all version entries except one (rename it to hilt, for example) and set its version to 2.51.1:

hilt = "2.51.1"

Now update the artifacts to only use this version instead.

Note: androidxHiltNavigationCompose has an independent versioning and must stay separate (with version 1.2.0).

With this out of the way you also need to update your module level gradle file.

Throw these two out:

ksp(libs.dagger.compiler)
ksp(libs.androidx.hilt.compiler)

And libs.hilt.compiler needs to be provided to ksp instead of implementation:

ksp(libs.hilt.compiler)

That's it, with this cleaned up gradle setup your code should work.

Sign up to request clarification or add additional context in comments.

1 Comment

been trying a few hours to fix this and it works! All the different hilt and dagger versions are confusing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.