google / dagger

A fast dependency injector for Android and Java.
https://dagger.dev
Apache License 2.0
17.35k stars 2k forks source link

java.lang.IllegalArgumentException: CreationExtras must have a value by `SAVED_STATE_REGISTRY_OWNER_KEY` #4320

Open RowlandOti opened 4 weeks ago

RowlandOti commented 4 weeks ago

When running project that has HILT, I am getting the following crash caused by:

val createReceiptViewModel: CreateReceiptViewModel = hiltViewModel<CreateReceiptViewModel>(key = "create_bill_viewmodel")

on the stacktrace:

FATAL EXCEPTION: main
Process: com.rowland.spendysync, PID: 9814
java.lang.IllegalArgumentException: CreationExtras must have a value by `SAVED_STATE_REGISTRY_OWNER_KEY`
at androidx.lifecycle.SavedStateHandleSupport.createSavedStateHandle(SavedStateHandleSupport.kt:89)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$2.create(HiltViewModelFactory.java:100)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:170)
at androidx.lifecycle.ViewModelProvider$Factory.create(ViewModelProvider.android.kt:158)

Dependencies:

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.1"
implementation "androidx.lifecycle:lifecycle-common-java8:2.8.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.1"

implementation "androidx.navigation:navigation-ui-ktx:2.8.0-beta02"
implementation "androidx.navigation:navigation-compose:2.8.0-beta02"

implementation "com.google.dagger:hilt-android:2.51.1"
ksp "com.google.dagger:hilt-android-compiler:2.51.1"
implementation "androidx.hilt:hilt-navigation-compose:1.2.0"

This issue only happens when I try to consume a library that is compiled with KMP

RowlandOti commented 4 weeks ago

To fix this, I had to use:

@Composable
fun Navigation(navController: NavHostController) {

    NavHost(navController, startDestination = Screen.Main.route) {
        navigation(startDestination = Screen.Home.route, route = Screen.Main.route) {
            composable(Screen.Home.route) {
           val createReceiptViewModel: CreateReceiptViewModel = hiltViewModel<CreateReceiptViewModel>()
            }
}
}

instead of :

@Composable
fun Navigation(navController: NavHostController) {
   val createReceiptViewModel: CreateReceiptViewModel = hiltViewModel<CreateReceiptViewModel>()
    NavHost(navController, startDestination = Screen.Main.route) {
        navigation(startDestination = Screen.Home.route, route = Screen.Main.route) {
            composable(Screen.Home.route) {
            }
}
}

Notice the difference in where ViewModel is initialized.

Chang-Eric commented 3 weeks ago

This CreationExtra is generally added by the owner, like here in ComponentActivity. There's similar code in Fragments and other places.

This doesn't quite seem like a Hilt issue. If you try this with a non-Hilt ViewModel that uses a SavedStateHandle, do you get this error?

RowlandOti commented 1 week ago

This doesn't quite seem like a Hilt issue. If you try this with a non-Hilt ViewModel that uses a SavedStateHandle, do you get this error?

@Chang-Eric unfortunately I only get this error when using KMP module and HIlt - unless I add the viewModel manually by by-passing Hilt. If I convert KMP to just normal Java/Android module, the error goes a away. (Same dependency versions between the two) . My project is a pure Jetpack compose.

Chang-Eric commented 1 week ago

Did you check that the owner adds that key in getDefaultViewModelCreationExtras() as I linked for ComponentActivity? What's the owner of the ViewModel?