jetpack compose viewModel() is giving error "has no zero argument constructor" with hilt

Viewed 4832

In my project, compose viewModel() method is giving error "has no zero argument constructor" when I am using hilt.

@Composable
    fun HomeScreen(homeViewModel: HomeViewModel = viewModel()) {
    ...
    }
    
    @HiltViewModel
    class HomeViewModel @Inject constructor(private val repository: Repository) :
        ViewModel() {
    ...
    }
@Module
@InstallIn(ViewModelComponent::class)
abstract class DataModule {
    @Binds
    abstract fun bindRepository(
        fakePuppyRepository: RepositoryImpl
    ): Repository
}

these are my dependencies

implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'
    implementation 'androidx.activity:activity-compose:1.3.0-alpha03'
    implementation "androidx.navigation:navigation-compose:1.0.0-alpha08"
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
    implementation 'androidx.compose.runtime:runtime-livedata:1.0.0-beta01'
    implementation "com.google.dagger:hilt-android:$hilt_version"
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
    kapt "com.google.dagger:hilt-compiler:$hilt_version"
    kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
4 Answers

Based on your dependencies, I suspect you are using NavController/NavHost.

Add this dependency: androidx.hilt:hilt-navigation-compose:1.0.0-alpha01

Now in your composable which defines NavController, call HomeScreen as follows:

import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltNavGraphViewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController

...

@Composable
fun Main() {
  val navController = rememberNavController()
  NavHost(navController, startDestination = "home"){
    composable("home") {
      val model: HomeViewModel = hiltNavGraphViewModel(it)
      HomeScreen(model)
    }
  }
}

...

hiltNavGraphViewModel(...) can also be replaced with viewModel(HiltViewModelFactory(LocalContext.current, backStackEntry)) (from https://github.com/google/dagger/issues/2166#issuecomment-769162910)

The hiltNavGraphViewModel() extension has been deprecated. You can use hiltViewModel() instead if you use Navigation and Hilt.

First, add this dependency:

implementation 'androidx.hilt:hilt-navigation-compose:1.0.0-alpha03'

And now you can use hiltViewModel() together with Navigation.

@Composable
fun MyApp() {
    NavHost(navController, startDestination = startRoute) {
        composable("example") { backStackEntry ->
            // Creates a ViewModel from the current BackStackEntry
            // Available in the androidx.hilt:hilt-navigation-compose artifact
            val exampleViewModel = hiltViewModel<ExampleViewModel>()
            ExampleScreen(exampleViewModel)
        }
        /* ... */
    }
}

More information: Hilt and Navigation

Happened to me when I set my ViewModel inside a package called new.

Let's say my base package is com.example.appname, I created a new pakage called new and I had com.example.appname.new, every other ViewModel factories were created successfully by Hilt with the exception the one inside of package new.

  1. Rename the package with name new, it looks like it is reserved.
  2. Move your ViewModel to another location.

Make sure your Activity/Fragments which enclose the composables have @AndroidEntryPoint and you have the latest version of hilt dependencies.

Related