Hilt creating different instances of view model inside same activity

前端 未结 2 1441
伪装坚强ぢ
伪装坚强ぢ 2021-01-06 12:44

After recently migrating from Dagger to Hilt I started observing very strange behavior with respect to ViewModels. Below is the code snippet:


@HiltAndroidApp         


        
相关标签:
2条回答
  • 2021-01-06 13:36

    When you use by viewModels, you are creating a ViewModel scoped to that individual Fragment - this means each Fragment will have its own individual instance of that ViewModel class. If you want a single ViewModel instance scoped to the entire Activity, you'd want to use by activityViewModels

    private val homeViewModel by activityViewModels<HomeViewModel>()
    
    0 讨论(0)
  • 2021-01-06 13:37

    What Ian says is correct, by viewModels is the Fragment's extension function, and it will use the Fragment as the ViewModelStoreOwner.

    If you need it to be scoped to the Activity, you can use by activityViewModels.

    However, you typically don't want Activity-scoped ViewModels. They are effectively global in a single-Activity application.

    To create an Activity-global non-stateful component, you can use the @ActivityRetainedScope in Hilt. These will be available to your ViewModels created in Activity or Fragment.

    To create stateful retained components, you should rely on @ViewModelInject, and @Assisted to get a SavedStateHandle.

    There is a high likelihood that at that point, instead of an Activity-scoped ViewModel, you really wanted a NavGraph-scoped ViewModel.

    To get a SavedStateHandle into a NavGraph-scoped ViewModel inside a Fragment via Hilt's @Assisted annotation, you can (EDIT: can't) use:

    //@Deprecated
    //inline fun <reified T : ViewModel> Fragment.hiltNavGraphViewModels(@IdRes navGraphIdRes: Int) =
    //viewModels<T>(
    //    ownerProducer = { findNavController().getBackStackEntry(navGraphIdRes) },
    //    factoryProducer = { defaultViewModelProviderFactory }
    //)
    

    .

    EDIT: Due to https://github.com/google/dagger/issues/2152 this above approach doesn't work, so what can work is to use accessors and building the NavGraph-scoped AbstractSavedStateViewModelFactory directly with accessors. It's a bit messy at the moment because ActivityRetainedComponent is hard to access, so stay tuned for a better solution...

    0 讨论(0)
提交回复
热议问题