We knew that in order to access Application
context like need to find a resource string or system service we extend our ViewModel with AndroidViewModel
while passing extra arguments to a ViewModel requires a factory that extend ViewModelProvider.NewInstanceFactory()
. My question is when you are using AndroidViewModel
you don't need to pass Application
as a parameter in constructing your ViewModel but when using a factory you will need to pass Application context along with your extra argument.
Is getActivity().getApplication() being done internally when just using AndroidViewModel
?
Is it okay to explicitly pass getActivity().getApplication()
in Fragment to your ViewModel factory?
Sample
ViewModel that only needs Application context
class AssetViewModel(application: Application) : AndroidViewModel(application) {
}
The above ViewModel can be construct in Fragment just like the default way.
val assetViewModel = ViewModelProvider(this).get(AssetViewModel::class.java)
However with a factory you will be doing it like this
class NewsVideoViewModelFactory(private val application: Application, private val baseUrl: String) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return NewsVideoViewModel(application, baseUrl) as T
}
}
class NewsVideoViewModel(application: Application, baseUrl: String) : AndroidViewModel(application){
}
Then construct it like this and relying on Activity
val viewModel = ViewModelProvider(this, NewsVideoViewModelFactory(requireActivity().application, baseUrl)).get(
NewsVideoViewModel::class.java)
Is this correct and not against the concept or best practice in using ViewModel?
In java, when you create a ViewModel through
AndroidViewModel
, you have to pass the Application parameter, so for the question:You have explicitly passed the Application context to the
AndroidViewModel
. In that class there is a methodgetApplication()
to receive the argument that passed. The second one:It is absolutely fine