How would I access data from a deep-link inside of an Android's Architecture Components ViewModel
at its init-time. I have access to extras provided in the intent's Bundle
(intent.extras
) through a Hilt-injected SavedStateHandle
, but when opening the Activity through a deep-link, I only have a URI (intent.data
) on the Activity level, and nothing in the ViewModel
.
As an example, say I'm opening my activity through something like my-app://profile?id=123, how would I get access to that 123 ID from an AAC ViewModel at init-time?
One solution to this could be to intercept the creation of the view model. The ComponentActivity.viewModels()
extension allows changing the CreationExtras
, which will get passed to the SavedStateHandle
:
public inline fun <reified VM : ViewModel> ComponentActivity.viewModels(
noinline extrasProducer: (() -> CreationExtras)? = null,
noinline factoryProducer: (() -> Factory)? = null
): Lazy<VM>
By default, a ComponentActivity
creates extras for its view models through getDefaultViewModelCreationExtras()
, which only grabs extras from the intent, but passing a extrasProducer
, we can inject more things:
private val viewModel: SomeViewModel by viewModels(
extrasProducer = {
val extras = MutableCreationExtras(defaultViewModelCreationExtras)
intent?.data?.getQueryParameter("id")?.let { queryParamId ->
extras[DEFAULT_ARGS_KEY] = bundleOf("id" to queryParamId)
}
extras
}
)