Reputation: 13031
Looking at the Google docs for ViewModel
, they show the below sample code on how to get a ViewModel
:
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
When using the latest dependency android.arch.lifecycle:extensions:1.1.1
there is no such class ViewModelProviders
.
Going to the documentation for ViewModelProviders
, I saw a comment saying:
This class was deprecated in API level 1.1.0. Use ViewModelProvider.AndroidViewModelFactory
The problem is, when trying to use ViewModelProvider.AndroidViewModelFactory
, cannot find an equivalent of
method to get the instance of the ViewModel
.
What i tried doing:
ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)
Hence the name of the method create
, I get a new instance of the ViewModel every-time I call it, which is not what I am after.
Any ideas what is the replacement of deprecated code above?
Upvotes: 247
Views: 140984
Reputation: 95
Update: July 20 2022
private lateinit var binding: FragmentHomeBinding
private lateinit var homeMvvM : HomeViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeMvvM = ViewModelProvider(this)[HomeViewModel::class.java]
this works for me.
Upvotes: 3
Reputation: 367
Try adding this code in your build.gradle module level
android {
kotlinOptions {
freeCompilerArgs += [
'-Xjvm-default=enable'
]
}
}
Upvotes: 0
Reputation: 3437
//Activity ktx
implementation 'androidx.activity:activity-ktx:1.5.1'
//Fragment ktx
implementation 'androidx.fragment:fragment-ktx:1.5.1'
Simplest way of creating view models:
class MyViewModel() : ViewModel() {
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_some)
}
}
View Model With Constructor Arguments:
class MyViewModel(list:List<String>) : ViewModel() {
class Factory(list:List<String>) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return MyViewModel(list) as T
}
}
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels(){
MyViewModel.Factory(listOf<String>("a"))}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Upvotes: 1
Reputation: 2687
I am using Library of Lifecycle 2.3.1 and add below dependency in build.gradle (Module-level)
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-extensions-ktx:2.2.0'
implementation 'androidx.activity:activity-ktx:1.4.0'
implementation 'androidx.fragment:fragment-ktx:1.3.6'
Declare viewModels() in your Kotlin code as per below:
import androidx.fragment.app.viewModels
private val cartViewModel: CartViewModel by viewModels()
Upvotes: 0
Reputation: 761
You can use something like this:
private val sharedViewModel: SharedViewModel by viewModels(ownerProducer = { requireActivity() })
ownerProducer = { requireActivity() } // This is only required if you want to share same view model among different fragments.
Upvotes: 0
Reputation: 6166
I use lifecycle-extensions 2.2.0
version:
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
It should work, using ViewModelProvider
constructor.
// With ViewModelFactory
val viewModel = ViewModelProvider(this, YourViewModelFactory).get(YourViewModel::class.java)
//Without ViewModelFactory
val viewModel = ViewModelProvider(this).get(YourViewModel::class.java)
2020/5/15 Update
I found another elegant way to achieve this, Android KTX can help
implementation "androidx.fragment:fragment-ktx:1.2.4"
val viewmodel: MYViewModel by viewModels()
val viewmodel: MYViewModel by viewModels { myFactory } //With factory
Ref: https://developer.android.com/reference/kotlin/androidx/fragment/app/package-summary#viewmodels
2020/06/25: corrected the case of the delegate
Upvotes: 479
Reputation: 7538
This answer is for Java but you can understand main point. Solution is that you need use ViewModelProvider because ViewModelProviders deprecated:
//Do not forget import it.
import androidx.lifecycle.AndroidViewModel;
ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
Example usage is:
YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
Also, do not forget update Gradle Dependencies: Check here for last versions of them
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'
!!! However, be careful because some answers recommend this solution but it did not work for me:
yourViewModel = new ViewModelProvider(this).get(YourViewModel.class);
Because when I used this way, I got below Error Message:
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.canerkaseler.mvvmexample.ViewModel
Upvotes: 3
Reputation: 7077
Simply update from
ViewModelProviders.of(this, provider).get(MainActivityViewModel::class.java)
to
ViewModelProvider(this, provider).get(MainActivityViewModel::class.java)
Upvotes: 1
Reputation: 1
I was facing the same issue. if anything doesn't work try this piece of code into your oncreate and edit it according to your file and boom you are gtg
val model = ViewModelProvider(viewModelStore,ViewModelProvider.AndroidViewModelFactory.getInstance(application)).get(MainActivityViewModel::class.java)
// you just need to change the model class
Upvotes: 0
Reputation: 312
I'm using factory.
ViewModelProvider.AndroidViewModelFactory
.getInstance(getApplication())
.create(DashboardViewModel.class);
Upvotes: 2
Reputation:
I kept trying and ended up with this solution in Kotlin, you should be able to try it in java too.
MainActivity.kt
val provider : ViewModelProvider = ViewModelProvider(this)
val VM = provider.get(ViewModelClass::class.java)
build.gradle
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0"
Current version of the lifecycle libraries is 2.3.0 as of 2/2/2021, Refer to https://developer.android.com/jetpack/androidx/releases/lifecycle to check for current version.
Upvotes: 2
Reputation: 22905
Deprecated From:
import androidx.lifecycle.ViewModelProviders;
To:
import androidx.lifecycle.ViewModelProvider;
Deprecated From:
ViewModelProviders.of(this, provider).get(VM::class.java)
To:
ViewModelProvider(this, provider).get(VM::class.java)
Upvotes: 78
Reputation: 4206
In case you watch a video from Udacity
where you create a GameViewModel
and you do not want to write deprecated code just replace:
viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)
with the following code:
viewModel = ViewModelProvider(this).get(GameViewModel::class.java)
and return back to reading ASAP!!
Upvotes: 14
Reputation: 1007584
UPDATE 2020-06-16: Presently ViewModelProviders
is deprecated and should no longer be used. This question and answer were from late 2018, when that was not the case. This question and answer are also for the older Architecture Components edition of ViewModelProviders
, not the AndroidX edition.
When using the latest dependency
android.arch.lifecycle:extensions:1.1.1
there is no such classViewModelProviders
.
Yes, there is. To demonstrate this:
Create a new project in Android Studio 3.2.1 (with Kotlin, minSdkVersion
21, "empty activity" template)
Add android.arch.lifecycle:extensions:1.1.1
to the dependencies of the app
module
This will give you an app/build.gradle
like:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.commonsware.myandroidarch"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'android.arch.lifecycle:extensions:1.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
You will then see that library show up in "External Libraries" with that class:
And you will be able to reference that class:
package com.commonsware.myandroidarch
import android.arch.lifecycle.ViewModelProviders
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val provider = ViewModelProviders.of(this)
}
}
Going to the documentation for ViewModelProviders, I saw a comment saying: This class was deprecated in API level 1.1.0. Use ViewModelProvider.AndroidViewModelFactory
That comment is underneath the ViewModelProviders.DefaultFactory
class entry and refers to that class, not ViewModelProviders
:
Any ideas what is the replacement of deprecated code above?
Use ViewModelProviders
.
Upvotes: 47
Reputation: 71
Use this:
YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
Upvotes: 6
Reputation: 119
When you use dagger then u'll pass factory in constructor
MobileViewModel mobileViewModel = new ViewModelProvider(this,providerFactory).get(MobileViewModel.class);
Upvotes: 2
Reputation: 241
You can use this instead:
viewModel= ViewModelProvider(this).get(YourViewModel::class.java)
"this" in the parentheses is the owner of YourViewModel instance.
Upvotes: 5
Reputation: 5595
Early in 2020, Google have deprecated the ViewModelProviders class, in version 2.2.0 of the androidx lifecycle library.
It's no longer necessary to use ViewModelProviders to create an instance of a ViewModel, you can pass your Fragment or Activity instance to the ViewModelProvider constructor instead.
If you use the code like:
val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)
you'll get a warning that ViewModelProviders has been deprecated.
To avoid using deprecated libraries, make the following changes:
In the build.gradle (Module: app) file, use version 2.2.0 of the lifecycle components:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation "androidx.activity:activity-ktx:1.1.0"
If you want to use the ViewModel from a Fragment instead, use
implementation "androidx.fragment:fragment-ktx:1.2.2"
fragment-ktx automatically includes activity-ktx, so you don't need to specify both in the dependencies.
You need to specify Java 8 in the android section :
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.kgandroid.calculator"
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner
"androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
kotlinOptions { jvmTarget = "1.8" }
}
In your Fragment or Activity, change the import to:
import androidx.activity.viewModels
The code to create a ViewModel then becomes:
val viewModel: CalculatorViewModel by viewModels()
instead of
val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)
Use the viewModel object as :
val viewModel: CalculatorViewModel by viewModels()
viewModel.newNumber.observe(this, Observer<String> {
stringResult -> newNumber.setText(stringResult)
})
where newNumer is a LiveData object
In a Fragment that you want to share the Activity's ViewModel, you'd use
val viewModel: CalculatorViewModel by activityViewModels()
That's the equivalent of passing the Activity instance in the (deprecated) ViewModelProviders.of()
function.
Upvotes: 37
Reputation: 3265
Actually, what does the ViewModelProviders.of()
method do under the hood?
@Deprecated
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
return new ViewModelProvider(fragment);
}
It takes Fragment
as an argument, creates ViewModelProvider
object and passes the fragment directly to ViewModelProvider
constructor.
We can use the same way too.
E.g. Before:
OurViewModel mOurViewModel = ViewModelProviders.of(this).get(OurViewModel.class);
After:
OurViewModel mOurViewModel = new ViewModelProvider(this).get(OurViewModel.class);
Upvotes: 15
Reputation: 869
Try this...
LocationViewModel locationViewModel = new ViewModelProvider(this).get(LocationViewModel.class);
Upvotes: -1
Reputation: 415
I'm no expert but i have a line of code that solved my problem in Java. Hope this helps someone.
viewModel =
new ViewModelProvider
.AndroidViewModelFactory(getApplication())
.create(ViewModel.class);
As i said i would love to provide more details, but this fixed this problem for me.
Upvotes: 3
Reputation: 1767
As of 2.2.0. the lifecycle-extensions has been deprecated. Refer to Google Documentation.
This is the cut from the page:
The APIs in lifecycle-extensions have been deprecated. Instead, add dependencies for the specific Lifecycle artifacts you need.
The new libraries are:
// ViewModel and lifecycle support for java
implementation "androidx.lifecycle:lifecycle-viewmodel:${versions.lifecycle}"
implementation "androidx.lifecycle:lifecycle-livedata:${versions.lifecycle}"
// ViewModel and lifecycle support for kotlin
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.lifecycle}"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.lifecycle}"
The new code for JAVA:
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
Or for Kotlin:
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
Upvotes: 61
Reputation: 1307
I'm using android X
and also had this issue.
First of all, you should add these dependencies to your Gradle
:
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
In my case, the $lifecycle_version was 2.2.0-rc02
Second:
The import for the ViewModelProvider
should be:
import androidx.lifecycle.ViewModelProvider
Than you can initial your vIewModel like the examples below:
val viewModel = ViewModelProvider(this, YourFactoryInstace).get(MainViewModel::class.java)
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
Upvotes: 9
Reputation: 729
If you use Kotlin, you can use the property delegate viewModels()
like this:
val viewModel: YourViewModel by viewModels()
Source: https://forums.bignerdranch.com/t/solution-to-deprecated-method-viewmodelproviders-of/16833
Upvotes: 7
Reputation: 1371
ViewModelProviders.of() has been deprecated.
Use ViewModelProvider constructors directly as they now handle the default ViewModelProvider.Factory role.
mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
Upvotes: 26
Reputation: 121
Use ViewModelProvider directly instead of user ViewModelProviders.of() as mentioned in the docs.
ViewModelProvider(this).get(XViewModel::class.java)
https://developer.android.com/reference/androidx/lifecycle/ViewModelProviders
Upvotes: 12
Reputation: 1
As @FantasyFang mentioned in his answer, use the lastest version for the lifecycle:lifecycle-extensions
which in this moment is 2.2.0-alpha03
. So you should add in your build.gradle file the following line:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha03'
For those who are using Java, to solve this, pass those arguments directly to ViewModelProvider's constructor:
MyViewModel viewModel = new ViewModelProvider(this, myViewModelFactory).get(MyViewModel.class);
Or if you don't use a factory, simply use:
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
Without passing your the factory object.
Upvotes: 104
Reputation: 2539
Probably you can just use:
val viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)
without needing to add android.arch.lifecycle:extensions:1.1.1
as the dependency.
Upvotes: 21
Reputation: 1204
Yes @Tarek, it is deprecated. Use now with AndroidX:
val yourViewModel = ViewModelProvider.NewInstanceFactory().create(YourVideoModel::class.java)
Upvotes: 14
Reputation: 12
it should work this way
viewModel = ViewModelProviders.of(this@MainActivity).get(MainActivityViewModel::class.java)
Upvotes: -7