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