Hilt creating different instances of view model inside same activity

前端 未结 2 1567
伪装坚强ぢ
伪装坚强ぢ 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条回答
  •  慢半拍i
    慢半拍i (楼主)
    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  Fragment.hiltNavGraphViewModels(@IdRes navGraphIdRes: Int) =
    //viewModels(
    //    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...

提交回复
热议问题