After recently migrating from Dagger to Hilt I started observing very strange behavior with respect to ViewModels. Below is the code snippet:
@HiltAndroidApp
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...