If you want to use a shared view model in a fragment you have to use by activityViewModels() instead of by viewModels().
Why does the next line work but by viewModels() doesn't?
ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
Because by default viewModels() has its ownerProducer argument value as { this }. To understand it better here is the source code:
@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this },
noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)
As you can see it is an extension function for Fragment class. It means that the ViewModelStoreOwner is the fragment. As soon as the fragment is removed from the stack all view models it stores in view model store are gone.
But if you use by activityViewModels() you use Activity as view model store owner. Notice use of requireActivity().viewModelStore instead of ownerProducer().viewModelStore which is a Fragment by default.
@MainThread
inline fun <reified VM : ViewModel> Fragment.activityViewModels(
noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { requireActivity().viewModelStore },
factoryProducer ?: { requireActivity().defaultViewModelProviderFactory })
Eventually, createViewModelLazy is calling
ViewModelProvider(store, factory).get(viewModelClass.java)
which is the equivalent of you creating view model by hand using
ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
How to fix the issue?
Use by activityViewModels():
@AndroidEntryPoint
...
private val viewModel: SharedViewModel by activityViewModels()
Note: by activityViewModels() and by viewModels() are just lazy load implementations of the ViewModelProvider(...).get(...).