androidandroid-jetpack-composeandroid-navigation

How does SavedStateHandle provide navigation arguments?


In Android Compose navigation, navigation arguments are populated in SavedStateHandle which can then be accessed in a ViewModel. I have done this in practice and implementation is well outlined here: https://stackoverflow.com/a/69145748/12385518.

My problem is I cannot find any documentation on why/how this is happening. In fact I cannot even find official documentation that even mention navigation arguments being in SavedStateHandle at all. I would love to read more about this. I have read these documents (and more) but found nothing on the topic:

https://developer.android.com/topic/libraries/architecture/viewmodel-savedstate https://developer.android.com/reference/androidx/lifecycle/SavedStateHandled

It seems to be a very nice technique for passing around navigation arguments, however since it isn't mentioned anywhere I am considering transitioning to another technique.


Solution

  • Here's how navigation arguments are passed to a ViewModel.

    1. When you call NavController.navigate(route, args) a NavBackStackEntry is created (source).

    2. NavBackStackEntry creates a SavedStateViewModelFactory which, as its name suggests, is a factory for creating ViewModels with a SavedStateHandle (source).

    3. NavBackStackEntry implements HasDefaultViewModelProviderFactory and exposes its factory from the previous step via the defaultViewModelProviderFactory property (source).

    4. Crucially, HasDefaultViewModelProviderFactory also has another property: defaultViewModelCreationExtras. This contains extra data fields which are used when constructing a ViewModel. The navigation arguments are stored here (source).

    5. When a viewModel creation method, such as hiltViewModel, is called it will check whether the ViewModelStoreOwner (in this case the NavBackStackEntry) implements HasDefaultViewModelProviderFactory. If it does, then it'll pass those extras (the navigation arguments) to the view model factory (source).

    6. The view model factory, in this case SavedStateViewModelFactory, then creates the SavedStateHandle, populates it with the navigation arguments (the extras), and supplies it to a newly created ViewModel so it has access to them (source).