New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Hilt] Multiple viewmodel instances with different keys crash #2328
Comments
I've run into the same issue when switching from the AndroidX hilt-lifecycle-viewmodel to the dagger hilt view model. I believe the core of the issue is that |
Yup - Part of the problem is that We are working on a long term solution to have 'extras' be propagated via Sadly, I don't have a workaround recommendation for this issue, I can only say to make distinct ViewModel classes with a shared parent since the ViewModel class is the key used. We could try to make |
in my current use-case distinct ViewModels won't work, I'm currently using the ViewModel framework to load additional complex data about individual items in a recycler view. Each item gets its own distinct instance of the ViewModel and the key is based off the unique id of the recycler view item. I'll probably just rework my use-case to store all the individual item ViewModels in a single parent ViewModel when I have a chance, until then I'll hold off on upgrading |
This isn't actually a Hilt issue. If you weren't using AbstractSavedStateViewModelFactory, only one of your ViewModels would be stored in the store, because the default key in the ViewModelStore is the canonical name of the ViewModel. IIRC the code says "//TODO: log a warning". So N-1 viewModels would actually not even be stored across config changes. Anyway, the AbstractSavedStateViewModelFactory is a KeyedFactory So try
Oh. |
This is the problem this issue is surfacing, using that method call with 2 different keys but the same ViewModel class doesn't work with the current hilt ViewModel support because it is implementing |
Oh.... It stopped being an AbstractSavedStateViewModelFactory. I knew it used to be one. Yeah, I'd consider that a Hilt issue. 🤔 |
I have tried several different ViewModelFactories, including the |
Just a quick summary, we are working on fixing this, but unfortunately just switching back to AbstractSavedStateViewModelFactory will not work due to injection timing issues and the SavedStateHandle. As @danysantiago mentioned above, we're looking at some long term solutions like that in https://android-review.googlesource.com/c/platform/frameworks/support/+/1535760. Unfortunately, until then, HiltViewModels will not be able to support multiple keys. |
Any update about this issue? |
Seems the changes linked in #2328 (comment) has been fixed in https://issuetracker.google.com/issues/188541057. But it seems that it hasn't been released yet. |
Multi-instance is a very important feature for some type of project, Hope it can be fixed soon Thanks |
it relies on this new "ViewModel CreationExtras" thingy 😅 |
Any new about this issue? |
Any updates? We really need this. |
The CreationExtras change that we need for this is unfortunately still in alpha https://developer.android.com/jetpack/androidx/releases/lifecycle#2.5.0-alpha01. Once that is stable, I think we can update Hilt's ViewModelFactory to pass through CreationExtras and then I think it would just work since the key is now derived from that instead of via that |
androidx.lifecycle moved to beta: Version 2.5.0-beta01 🥳, meaning the API is now stable enough to proceed with this? |
androidx.lifecycle moved to rc: Version 2.5.0-rc01 now, stable enough to proceed with this? |
We need it to actually hit the stable release. After that happens (which since it is in RC should be relatively soon hopefully), we should be able to make the change in Hilt and do a release shortly after. |
Lifecycle hit 2.5.0 stable! |
Yes, it should now be possible. |
any update on this ? |
Also waiting for this much needed feature |
I have updated to the latest version 2.5.0, but this problem still exists. |
Just upgrading to 2.5.0 isn't enough, it requires a change on the Hilt side. I have a PR to do that, but it has been delayed due to various dependency issues that need sorting out. We're aiming to get it submitted and then do a release next week, assuming no other issues come up. |
Forgot to tag this issue in 74ea765, but that commit should fix this issue. |
And the fix is released 🎉 https://github.com/google/dagger/releases/tag/dagger-2.43 Great job 👏 |
What is the standard then for initiating hiltViewModels() with keys? |
Until Hilt provides an API to use the key explicitly, you easily create one yourself using the FYI: I tested this in my own library and it works like a charm https://github.com/sebaslogen/resaca/blob/main/resacahilt/src/main/java/com/sebaslogen/resaca/hilt/ScopedMemoizers.kt#L57 |
Thank you for this - I tried your library and it seems that only variables are scoped, while running coroutines on viewmodelscope are not. How can I fix this? |
@tommyzat I'm not sure I fully understand your question correctly, but if it's about my library (https://github.com/sebaslogen/resaca) it's better to move the discussion out of this Hilt/Dagger issue. You can either open an issue on the Resaca GitHub space or contact me on Twitter @sebaslogen |
now you can basically create fun: import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.HiltViewModelFactory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavBackStackEntry
@Composable
inline fun <reified VM : ViewModel> hiltViewModel(key: String): VM {
val viewModelStoreOwner =
if (checkNotNull(LocalViewModelStoreOwner.current) is NavBackStackEntry) {
checkNotNull(LocalViewModelStoreOwner.current) { "ViewModelStoreOwner is null" }
} else null
return viewModel(
key = key,
factory = if (viewModelStoreOwner is NavBackStackEntry) {
HiltViewModelFactory(
LocalContext.current,
viewModelStoreOwner
)
} else null
)
} and then usage like: YourComposableWithViewModelArg(
viewModel = hiltViewModel(key = "MyUniqueViewModelKey"),
// ... rest of the arguments
) |
supported since 1.1.0-alpha01 of androidx.hilt:hilt-navigation-compose with key param |
Hello
I have recently swapped to Hilt. Before we used dagger and had the following code which would allow us to have multiple instance of the same viewmodel, but with different keys:
Example of use:
But when I'm using Hilt I get the following error when I try to get my second instance:
Doesn't Hilt allow multiple viewModels with different keys?
The text was updated successfully, but these errors were encountered: