Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AndroidViewModel instantiated without passing application context?

I am currently digging through the Android Room with a View sample app, full source code available here. In this project, an WordViewModel of type AndroidViewModel is defined:

class WordViewModel(application: Application) : AndroidViewModel(application)

Note how the constructor requires an Application instance to be passed in. Yet when I check the MainActivity, the WordViewModel is retrieved without passing in the Application instance:

// Get a new or existing ViewModel from the ViewModelProvider.
mWordViewModel = new ViewModelProvider(this).get(WordViewModel.class);

How is that possible, how can the WordViewModel be retrieved without passing in the Application instance and without using a custom factory?

like image 929
stefan.at.wpf Avatar asked Dec 31 '22 06:12

stefan.at.wpf


1 Answers

AndroidX-Activity 1.2.0's ComponentActivity (and therefore AppCompatActivity) implements HasDefaultViewModelProviderFactory, which returns an ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()) from your Activity/Fragment by default, allowing you to get the application from this AndroidViewModelFactory without you having to explicitly pass it.

Then, this factory instantiates your ViewModel via reflection using a __(application) constructor.

It's generally a better idea to use SavedStateViewModelFactory in order to be able to receive a SavedStateHandle in a similar manner (___(application, savedStateHandle)) though.

So to fix the problem, you need to add up-to-date versions of core-ktx, activity-ktx and fragment-ktx explicitly in your code.

like image 53
EpicPandaForce Avatar answered Jan 13 '23 10:01

EpicPandaForce