95

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.

peterh
  • 11,875
  • 18
  • 85
  • 108
Anchal Arora
  • 1,081
  • 1
  • 7
  • 8

14 Answers14

159

Simply replace:

This:

boardViewModel = ViewModelProviders.of(this).get(BoardViewModel::class.java)

With this:

boardViewModel = ViewModelProvider(this).get(BoardViewModel::class.java)
KnowIT
  • 2,392
  • 1
  • 18
  • 16
  • 43
    In Java: "boardViewModel = new ViewModelProvider(this).get(BoardViewModel.class)" – Elletlar Jan 31 '20 at 11:29
  • 1
    boardViewModel = ViewModelProvider(this).get("model", BoardViewModel::class.java) only compile for me in latest versions. – SkorpEN Apr 17 '20 at 06:47
  • For me .get(UserViewModel::class.java) has red underline that is for some reason saying " Type parameter bound for T in operator fun get ( modelClass: Class ) : T is not satisfied: inferred type UserViewModel! is not a subtype of ViewModel! ". – Jevon Jul 23 '20 at 06:33
  • What does **this** stand for? – IgorGanapolsky Jul 26 '20 at 20:05
  • 1
    @IgorGanapolsky The UI controller (activity or fragment) you want to tie to the viewmodel. – Nekomajin42 Aug 01 '22 at 19:58
54

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 enter image description here

Milad Faridnia
  • 9,113
  • 13
  • 65
  • 78
Denis
  • 653
  • 5
  • 3
35

ViewModelProviders.of() has been deprecated. enter image description here

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)
Junaid
  • 1,301
  • 1
  • 15
  • 21
  • 4
    This did the trick in my case. Thanks! It's just nice to mention that I had to change some reded `this` to `getViewLifecycleOwner()` to avoid warnings. – JorgeAmVF Feb 26 '20 at 07:44
14

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 Fragments 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);
Amin Dannak
  • 155
  • 1
  • 7
10

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()
9

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)

Please click here to see the solution

9

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 }
Rajesh.k
  • 2,327
  • 1
  • 16
  • 19
7

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...

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 8
    to use `by viewModels()` you need to add this dependency `implementation 'androidx.fragment:fragment-ktx:1.2.0'` – Rafael Jan 29 '20 at 12:07
  • 1
    @CommonsWare I guess we should use below dependencies to instantiate view model For Fragments implementation 'androidx.fragment:fragment-ktx:x.x.x' For Activities implementation "androidx.activity:activity-ktx:x.x.x" – Vikash Kumar Tiwari Jan 30 '20 at 14:08
  • @VikashKumarTiwari: Yes, I believe that `by viewModels()` and `by activityViewModels()` are defined in the `fragment-ktx` and `activity-ktx` artifacts. – CommonsWare Jan 30 '20 at 14:17
  • 4
    @CommonsWare As per latest release Version 1.2.0 January 22, 2020 by viewModels() and by activityViewModels() are present in below dependency implementation 'androidx.fragment:fragment-ktx:1.2.0' Also, by viewModels() is to be used for viewmodel initialization in both activity and fragment. But by activityViewModels() can only be used in fragment to get parent activity's viewmodel. Moreover, while using implementation "androidx.activity:activity-ktx:x.x.x" We can access by viewModels() only in activity and it will not be accessed in fragment. – Vikash Kumar Tiwari Jan 30 '20 at 19:21
5

This code works for me

private lateinit var viewModel: MainViewModel
viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MainViewModel::class.java)
Samiul Islam Sami
  • 791
  • 13
  • 24
2

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
Attaullah
  • 3,856
  • 3
  • 48
  • 63
2

As ViewModelProviders got deprecated. You can now use the ViewModelProvider constructor directly. For more details how to use it, check here.

GoonerVJ
  • 21
  • 4
2

lifecycle-extensions 2.2.0 version:

implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

ViewModelProvider with constructor uses

 // With ViewModelFactory   
 val viewModel = ViewModelProvider(this, YourViewModelFactory).get(YourViewModel::class.java)


//Without ViewModelFactory
val viewModel = ViewModelProvider(this).get(YourViewModel::class.java)
Mayur Dabhi
  • 3,607
  • 2
  • 14
  • 25
0

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 }
Rajesh.k
  • 2,327
  • 1
  • 16
  • 19
0
private lateinit var vm: SRViewModel
private lateinit var adapter: StudentRecordsAdapter

Deprecated

vm = ViewModelProviders.of(this)[SRViewModel::class.java]

Use this line of code

vm=  ViewModelProvider(this)[SRViewModel::class.java]
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103