Looking at the Google docs for ViewModel
, they show the below sample code on how to get a ViewModel
:
val model = ViewModelProviders
You can use this instead:
viewModel= ViewModelProvider(this).get(YourViewModel::class.java)
"this" in the parentheses is the owner of YourViewModel instance.
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)
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);
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.
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.
If you have this implementation
'implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
Try to use
viewModel = MainViewModel()