As ViewModelProviders.of() is deprecated, how should I create object of ViewModel?
AndroidViewmodelAndroid Problem Overview
I have been trying to create an Object of ViewModel in an Activity but ViewModelProviders is deprecated So what's the alternative to create the ViewModel's object.
Android Solutions
Solution 1 - Android
Simply replace:
This:
boardViewModel = ViewModelProviders.of(this).get(BoardViewModel::class.java)
With this:
boardViewModel = ViewModelProvider(this).get(BoardViewModel::class.java)
Solution 2 - Android
This Gradle upgrade created the problem for me.
FROM
implementation 'androidx.core:core:1.1.0'
TO
implementation 'androidx.core:core:1.2.0'
IN MAIN ACTIVITY Java/Kotlin Files
This import statement
import androidx.lifecycle.ViewModelProviders
had to be changed to
import androidx.lifecycle.ViewModelProvider
This KOTLIN viewModel statement
viewModel = ViewModelProviders.of(this).get(MainActivityViewModel::class.java)
had to be changed to
viewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
and in JAVA
This line of JAVA code
mViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
had to be changed to
mViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
and then it all worked for me.
Based on: An outline of the steps that created the problem for me
Solution 3 - Android
> ViewModelProviders.of() has been deprecated.
Use ViewModelProvider constructors directly as they now handle the default ViewModelProvider.Factory role.
> Java
mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
> Kotlin
mainActivityViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
Solution 4 - Android
Instead of ViewModelProviders
we should now use ViewModelProvider
constructors and it has three:
public ViewModelProvider(ViewModelStoreOwner owner)
public ViewModelProvider(ViewModelStoreOwner owner, Factory factory)
public ViewModelProvider(ViewModelStore store, Factory factory)
1. If you are not using a ViewModelProvider.Factory
to pass additional arguments to your ViewModel
, you can use the first one. so:
viewModel = ViewModelProviders.of(this).get(YourViewModel.class);
can be replaced with:
viewModel = new ViewModelProvider(this).get(YourViewModel.class);
AppCompatActivity
and different kinds of Fragment
s are indirect subclasses of ViewModelStoreOwner
(see the complete list of its known subclasses here), so you can use them in this constructor.
2. But if you are using a ViewModelProvider.Factory
, you should use the second or the third constructors:
viewModel = ViewModelProviders.of(this, viewModelFactory).get(YourViewModel.class);
can be replaced with:
viewModel = new ViewModelProvider(this, viewModelFactory).get(YouViewModel.class);
OR based on the documentation of ViewModelStore
:
> Use ViewModelStoreOwner.getViewModelStore() to retrieve a > ViewModelStore for activities and fragments.
viewModel = new ViewModelProvider(getViewModelStore(), viewModelFactory).get(YourViewModel.class);
Solution 5 - Android
ViewModelProviders.of() has been deprecated. You can pass a Fragment or FragmentActivity to the new ViewModelProvider(ViewModelStoreOwner) constructor to achieve the same functionality. (aosp/1009889)
Solution 6 - Android
The simple option for the next several months is to stick with stable or beta versions. ViewModelProviders
is only deprecated starting with 2.2.0
, presently in an alpha03
release.
For when you do move to 2.2.0
or higher of the lifecycle dependencies, your options depend on your language:
-
If you are using Java, use the
ViewModelProvider()
constructor, passing in your activity or fragment -
If you are using Kotlin, there is supposed to be a
by viewModels()
property delegate, though I am not finding it in the source code...
Solution 7 - Android
If you're using Kotlin, instead of:
private lateinit var viewModel: EntityGridViewModel
[...]
// Deprecated
viewModel = ViewModelProviders.of(this).get(EntityGridViewModel::class.java)
You can use the nicer:
private val viewModel: EntityGridViewModel by viewModels()
Solution 8 - Android
This code works for me
private lateinit var viewModel: MainViewModel
viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MainViewModel::class.java)
Solution 9 - Android
For java
:
Simply replace this:
viewModel = ViewModelProviders.of(this).get(YOUR_VIEW_MODEL::class.java)
With this:
viewModel = ViewModelProvider(this).get(YOUR_VIEW_MODEL::class.java)
if you are having your own factory then,
viewModel =
ViewModelProvider(this,YOUR_FACTORY).get(YOUR_VIEW_MODEL::class.java)
For kotlin
:
There is a nicer way to do this. you can add the below dependencies in app build.gradle
:
//for activity
implementation "androidx.activity:activity-ktx:1.3.0-alpha06"
//for fragment
implementation "androidx.fragment:fragment-ktx:1.3.2"
and then access the viewmodel like below:
private val viewmodel: YOUR_VIEW_MODEL by viewModels()
If you have your own view model factory then,
private val viewmodel: YOUR_VIEW_MODEL by viewModels { YOUR_VIEW_MODEL_FACTORY }
Solution 10 - Android
> This class is deprecated. > Use the constructors for ViewModelProvider directly. here
So instead of using this
ViewModelProviders.of(this).get(MyViewModel.class); - deprecated
Use this one
new ViewModelProvider(this).get(MyViewModel.class); - correct
Solution 11 - Android
As ViewModelProviders got deprecated. You can now use the ViewModelProvider constructor directly. For more details how to use it, check here.
Solution 12 - Android
you can add the below dependencies in app build.gradle
:
//for activity
implementation "androidx.activity:activity-ktx:1.2.2"
//for fragment
implementation "androidx.fragment:fragment-ktx:1.3.2"
and then use like below:
private val viewmodel: YOUR_VIEW_MODEL_CLASS_NAME by viewModels()
If you have your own view model factory then,
private val viewmodel: YOUR_VIEW_MODEL_CLASS_NAME by viewModels { YOUR_VIEW_MODEL_FACTORY }