ViewModelProviders is deprecated in 1.1.0

2020-02-08 10:20发布

问题:

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?

回答1:

When using the latest dependency android.arch.lifecycle:extensions:1.1.1 there is no such class ViewModelProviders.

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.



回答2:

I use lifecycle-extensions 2.2.0 version:

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

It should be 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)


回答3:

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.



回答4:

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)


回答5:

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



回答6:

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);


回答7:

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)


回答8:

Yes @Tarek, it is deprecated. Use now with AndroidX:

val yourViewModel = ViewModelProvider.NewInstanceFactory().create(YourVideoModel::class.java)


回答9:

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.



回答10:

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



回答11:

There is nothing about the get method that is deprecated. If you follow the Android Developer instructions then you should get the VM like this.

public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
    // Create a ViewModel the first time the system calls an activity's onCreate() method.
    // Re-created activities receive the same MyViewModel instance created by the first activity.

    MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
    model.getUsers().observe(this, users -> {
        // update UI
    });
  }
}

Here is the instructions on how to use ViewModels Here is the instructions on how to set up your project with the correct dependencies



回答12:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc03'

leftRightViewModel = ViewModelProvider.AndroidViewModelFactory(application).create(LeftRightViewModel::class.java)


回答13:

If you have this implementation

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

Try to use viewModel = MainViewModel()



回答14:

it should work this way

 viewModel = ViewModelProviders.of(this@MainActivity).get(MainActivityViewModel::class.java)