1.1.0中不推荐使用ViewModelProviders

时间:2018-12-23 12:53:44

标签: android android-gradle android-architecture-components android-viewmodel

查看ViewModel的{​​{3}},它们显示以下示例代码,说明如何获取ViewModel

val model = ViewModelProviders.of(this).get(MyViewModel::class.java)

使用最新的依赖项android.arch.lifecycle:extensions:1.1.1时,没有此类ViewModelProviders

ViewModelProvidersGoogle docs,我看到一条评论:

  

该类在API级别1.1.0中已弃用。使用ViewModelProvider.AndroidViewModelFactory

问题是,当尝试使用ViewModelProvider.AndroidViewModelFactory时,找不到等效的of方法来获取ViewModel的实例。

我尝试做的事情:

ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)

由于方法create的名称,每次调用它时我都会得到一个ViewModel的新实例,这不是我想要的。

有什么想法替换上面不推荐使用的代码吗?

27 个答案:

答案 0 :(得分:63)

我使用生命周期扩展2.2.0-alpha03版本:

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

使用ViewModelProvider构造函数应该可以正常工作。

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


//Without ViewModelFactory
val viewModel = ViewModelProvider(this).get(YourViewModel::class.java)

答案 1 :(得分:49)

从2.2.0开始。 lifecycle-extensions已弃用。请参阅Google Documentation

这是从页面上剪下来的:

生命周期扩展中的API已被弃用。相反,添加 所需的特定生命周期工件的相关性。

新库为:

// 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}"

JAVA的新代码:

viewModel = new ViewModelProvider(this).get(MyViewModel.class);

或者对于Kotlin:

viewModel = ViewModelProvider(this).get(MyViewModel::class.java)

答案 2 :(得分:42)

导入

不推荐自:

import androidx.lifecycle.ViewModelProviders;

收件人:

import androidx.lifecycle.ViewModelProvider;

使用

不推荐自:

ViewModelProviders.of(this, provider).get(VM::class.java)

收件人:

ViewModelProvider(this, provider).get(VM::class.java)

答案 3 :(得分:29)

2020年初, Google在androidx生命周期库的版本2.2.0中弃用了ViewModelProviders类

不再需要使用ViewModelProviders创建ViewModel的实例,您可以将Fragment或Activity实例传递给ViewModelProvider构造函数。

如果您使用如下代码:

val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)

您将收到 ViewModelProviders已过时的警告。

为避免使用不赞成使用的库,请进行以下更改:

  1. 在build.gradle(模块:app)文件中,使用生命周期的版本2.2.0 组件:

    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
    implementation "androidx.activity:activity-ktx:1.1.0"
    

    如果您想改用Fragment中的ViewModel,请使用

    implementation "androidx.fragment:fragment-ktx:1.2.2"
    

    fragment-ktx自动包含activity-ktx,因此您不需要 在依赖项中同时指定两者。

  2. 您需要在android部分中指定Java 8:

    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" }
    }
    
  3. 在“片段”或“活动”中,将导入更改为:

    导入androidx.activity.viewModels

  4. 然后,用于创建ViewModel的代码变为:

    val viewModel: CalculatorViewModel by viewModels()
    

    代替

    val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)
    

    将viewModel对象用作:

    val viewModel: CalculatorViewModel by viewModels()
    
    viewModel.newNumber.observe(this, Observer<String> { 
        stringResult -> newNumber.setText(stringResult) 
    })
    

    其中 newNumer是一个LiveData对象

    要共享活动的ViewModel的片段中,您将使用

    val viewModel: CalculatorViewModel by activityViewModels()
    

这等效于在(不推荐使用的)ViewModelProviders.of()函数中传递Activity实例。

答案 4 :(得分:25)

正如@FantasyFang在他的回答中提到的,对lifecycle:lifecycle-extensions使用最新版本,目前为2.2.0-alpha03。因此,您应该在build.gradle文件中添加以下行:

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

对于使用Java的用户,要解决此问题,请将这些参数直接传递到ViewModelProvider的constructor

MyViewModel viewModel = new ViewModelProvider(this, myViewModelFactory).get(MyViewModel.class);

或者,如果您不使用工厂,只需使用:

MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);

不传递工厂对象。

答案 5 :(得分:13)

实际上,ViewModelProviders.of()方法到底是做什么的?

@Deprecated
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
    return new ViewModelProvider(fragment);
}

它以Fragment作为参数,创建ViewModelProvider对象,并将片段直接传递给ViewModelProvider构造函数。

我们也可以使用相同的方式。

例如之前:

OurViewModel mOurViewModel = ViewModelProviders.of(this).get(OurViewModel.class);

之后:

OurViewModel mOurViewModel = new ViewModelProvider(this).get(OurViewModel.class);

答案 6 :(得分:9)

我正在使用android X,也遇到了这个问题。

首先,您应将以下依赖项添加到Gradle

implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" 

就我而言,$ lifecycle_version是2.2.0-rc02

第二: ViewModelProvider的导入应为:

import androidx.lifecycle.ViewModelProvider

比起下面的示例,您可以初始化vIewModel:

val viewModel = ViewModelProvider(this, YourFactoryInstace).get(MainViewModel::class.java)

val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

答案 7 :(得分:6)

  

使用最新的依赖项android.arch.lifecycle:extensions:1.1.1时,没有此类ViewModelProviders

是的,有。为了证明这一点:

  • 在Android Studio 3.2.1中创建一个新项目(使用Kotlin,minSdkVersion 21,“空活动”模板)

  • android.arch.lifecycle:extensions:1.1.1模块的依赖项中添加app

这将为您提供app/build.gradle,例如:

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'
}

然后您将看到该库显示在该类的“外部库”中:

External Libraries

您将能够引用该类:

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

转到ViewModelProviders的文档,我看到一条评论说:该类在API级别1.1.0中已弃用。使用ViewModelProvider.AndroidViewModelFactory

该注释位于ViewModelProviders.DefaultFactory类条目的下方,并且引用该类,而不是ViewModelProviders

Documentation Screenshot

  

有什么想法替换上面不推荐使用的代码吗?

使用ViewModelProviders

答案 8 :(得分:6)

使用此:

YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);

答案 9 :(得分:5)

如果您使用Kotlin,则可以使用属性委托viewModels(),如下所示:

val viewModel: YourViewModel by viewModels()

来源:https://forums.bignerdranch.com/t/solution-to-deprecated-method-viewmodelproviders-of/16833

答案 10 :(得分:5)

您可以改用它:

viewModel= ViewModelProvider(this).get(YourViewModel::class.java)
括号中的

“ this”是YourViewModel实例的所有者。

答案 11 :(得分:3)

我不是专家,但是我有一行代码可以解决Java中的问题。希望这对某人有帮助。

viewModel = 
new ViewModelProvider
.AndroidViewModelFactory(getApplication())
.create(ViewModel.class);

正如我所说,我想提供更多细节,但这为我解决了这个问题。

答案 12 :(得分:2)

我一直在尝试,最终在 Kotlin 中得到了这个解决方案,你应该也可以在 Java 中尝试它。

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"

截至 2021 年 2 月 2 日,生命周期库的当前版本为 2.3.0,请参阅 https://developer.android.com/jetpack/androidx/releases/lifecycle 查看当前版本。

答案 13 :(得分:2)

如果您观看来自Udacity的视频,并在其中创建了GameViewModel,并且不想编写不赞成使用的代码,则只需替换:

viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)

具有以下代码:

viewModel = ViewModelProvider(this).get(GameViewModel::class.java)
  

然后返回以尽快阅读!

答案 14 :(得分:2)

直接使用ViewModelProvider代替文档中提到的用户ViewModelProviders.of()。

ViewModelProvider(this).get(XViewModel::class.java)

https://developer.android.com/reference/androidx/lifecycle/ViewModelProviders

答案 15 :(得分:1)

我正在使用工厂。

ViewModelProvider.AndroidViewModelFactory
            .getInstance(getApplication())
            .create(DashboardViewModel.class);

答案 16 :(得分:1)

使用匕首时,您将在构造函数中通过工厂

  MobileViewModel mobileViewModel = new ViewModelProvider(this,providerFactory).get(MobileViewModel.class);

答案 17 :(得分:1)

此答案适用于Java,但您可以理解要点。解决方案是您需要使用 ViewModelProvider ,因为ViewModelProviders deprecated

SELECT UNITE_ENROLMENT.Session, UNITE.UniteCode, 
UNITE.UniteName, WORKSHOP.Location, WORKSHOP.Weekday, 
WORKSHOP.ClassTimes, CONCAT(TEACHER.FirstName," ",TEACHER.LastName) AS 
TeacherFullName, CONCAT(STUDENT.FirstName," ",STUDENT.LastName) AS 
StudentFullName, STUDENT.phone
FROM WORKSHOP_ENROLMENT
    JOIN STUDENT
        ON WORKSHOP_ENROLMENT.StudentID = STUDENT.StudentID
    JOIN WORKSHOP
        ON WORKSHOP.WorkshopID = WORKSHOP_ENROLMENT.WorkshopID
    JOIN TEACHER
        ON TEACHER.StaffID = WORKSHOP.StaffID
    JOIN UNIT_OFFERING
        ON UNIT_OFFERING.UnitOfferingID = WORKSHOP.UnitOfferingID
    JOIN UNITE
        ON UNITE.UniteCode = UNIT_OFFERING.UniteCode
    JOIN UNITE_ENROLMENT
        ON UNIT_OFFERING.UnitOfferingID = UNITE_ENROLMENT.UnitOfferingID
WHERE UNITE_ENROLMENT.Session = 3 AND  UNITE_ENROLMENT.Year = 2019
ORDER BY UNIT.UniteCode, WORKSHOP.Location, WORKSHOP.Weekday,
WORKSHOP.ClassTimes , StudentFullName

示例用法是

//Do not forget import it.
import androidx.lifecycle.AndroidViewModel;

ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);

另外,不要忘记更新 Gradle Dependencies Check here for last versions of them

YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);

!!!但是,请小心,因为一些答案推荐了此解决方案,但它对我不起作用:

implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'

因为我使用这种方式,所以出现了以下错误消息:

原因:java.lang.RuntimeException:无法创建com.canerkaseler.mvvmexample.ViewModel类的实例

@canerkaseler

答案 18 :(得分:1)

也许您可以使用:

val viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)

无需添加android.arch.lifecycle:extensions:1.1.1作为依赖项。

答案 19 :(得分:0)

关于get的方法deprecated没有什么。如果您遵循Android Developer的说明,则应该获得VM,就像这样。

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

以下是how to use ViewModels上的说明 这是有关如何设置project with the correct dependencies

的说明

enter image description here

enter image description here

答案 20 :(得分:0)

是@Tarek,已弃用。立即用于AndroidX:

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

答案 21 :(得分:0)

它应该以这种方式工作

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

答案 22 :(得分:0)

实现'androidx.lifecycle:lifecycle-extensions:2.2.0-rc03' leftRightViewModel = ViewModelProvider.AndroidViewModelFactory(application).create(LeftRightViewModel :: class.java)

答案 23 :(得分:0)

我遇到了同样的问题。如果有任何事情不起作用,请尝试将这段代码放入您的 oncreate 并根据您的文件和繁荣进行编辑,您就是 gtg

val model = ViewModelProvider(viewModelStore,ViewModelProvider.AndroidViewModelFactory.getInstance(application)).get(MainActivityViewModel::class.java)

//你只需要改变模型类

答案 24 :(得分:0)

ViewModelProviders.of()已被弃用。 enter image description here

直接使用ViewModelProvider构造函数,因为它们现在处理默认的ViewModelProvider.Factory角色。

 mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);

答案 25 :(得分:-1)

尝试一下...

 LocationViewModel locationViewModel = new ViewModelProvider(this).get(LocationViewModel.class);

答案 26 :(得分:-2)

如果您有此实现

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

尝试使用 viewModel = MainViewModel()