【问题标题】:ViewModelProviders is deprecated in 1.1.0ViewModelProviders 在 1.1.0 中已弃用
【发布时间】:2019-05-23 01:06:34
【问题描述】:

查看Google docsViewModel,他们展示了以下示例代码,了解如何获得ViewModel

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

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

documentationViewModelProviders,看到评论说:

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

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

我尝试做什么:

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

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

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

【问题讨论】:

  • 使用单例模式或改为AndroidX

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


【解决方案1】:

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

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

它应该可以工作,使用 ViewModelProvider 构造函数。

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


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

2020/5/15 更新

我找到了另一种优雅的方式来实现这一点,Android KTX 可以提供帮助

implementation "androidx.fragment:fragment-ktx:1.2.4"
val viewmodel: MYViewModel by viewModels()
val viewmodel: MYViewModel by viewModels { myFactory } //With factory

参考:https://developer.android.com/reference/kotlin/androidx/fragment/app/package-summary#viewmodels

2020/06/25:更正了代表的情况

【讨论】:

  • 我有点厌倦了 Google 不断的“折旧”周期。
  • ViewModelProviders.of() 已被弃用。您可以将 Fragment 或 FragmentActivity 传递给新的 ViewModelProvider(ViewModelStoreOwner) 构造函数以实现相同的功能。 (aosp/1009889)
  • Java 等效项:YourViewModel viewModel = new ViewModelProvider(this).get(YourViewModel.class);
  • 我担心有一天 Google 会弃用 TextViewEditText 并引入一个新组件。
  • androidx 生命周期视图模型 2.1.0 没有没有工厂的构造函数。简单地使用(this)不起作用。 ViewModelProvider(ViewModelStoreOwner, Factory) 和 ViewModelProvider(ViewModelStore, Factory) 是唯一的构造函数
【解决方案2】:

正如@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);

没有传递你的工厂对象。

【讨论】:

  • 您应该在 build.gradle 中使用以下内容: implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" 如 developer.android.com/jetpack/androidx/releases/lifecycle 中所述,生命周期扩展中的 API 已被弃用。相反,为您需要的特定生命周期工件添加依赖项。
【解决方案3】:

导入

弃用自:

<strike>import androidx.lifecycle.ViewModelProviders;</strike>

收件人:

import androidx.lifecycle.ViewModelProvider;

使用

弃用自:

<strike>ViewModelProviders.of</strike>(this, provider).get(VM::class.java)

收件人:

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

【讨论】:

  • 正是我想要的。
【解决方案4】:

从 2.2.0 开始。生命周期扩展已被弃用。参考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)

【讨论】:

  • 我们是保留 ViewModelProvider 还是必须重新创建它,在这种情况下,所有底层实例也将被销毁。如果我的想法是观察片段/活动的生命周期,我不打算重新创建它
  • 感谢包含 Java - 我们中的一些人仍然需要维护遗留代码。
【解决方案5】:

2020-06-16 更新目前ViewModelProviders 已弃用,不应再使用。这个问题和答案是从 2018 年底开始的,当时情况并非如此。此问题和答案也适用于 ViewModelProviders 的旧架构组件版本,而不是 AndroidX 版本。


当使用最新的依赖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'
}

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

您将能够引用该类:

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

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

使用ViewModelProviders

【讨论】:

  • @TareKKhoury:这就解释了!跟踪哪些模块需要哪些依赖项肯定是一个挑战。我很高兴听到你让它工作了!
  • 这不是真的,ViewModelProviders.of() 不再存在。
【解决方案6】:

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 (Module: 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. 在您的 Fragment 或 Activity 中,将导入更改为:

    导入 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 对象

    在您想要共享 Activity 的 ViewModel 的 Fragment 中,您将使用

    val viewModel: CalculatorViewModel by activityViewModels()
    

这相当于在(已弃用的)ViewModelProviders.of() 函数中传递 Activity 实例。

【讨论】:

    【解决方案7】:

    ViewModelProviders.of() 已被弃用。

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

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

    【讨论】:

      【解决方案8】:

      也许你可以使用:

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

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

      【讨论】:

        【解决方案9】:

        实际上,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);
        

        【讨论】:

        • 如果你实现一个工厂,你有另一种方式:ViewModelProvider 有一个构造函数,它需要一个 ViewModelStoreOwner 和一个 Factory
        【解决方案10】:

        是的@Tarek,它已被弃用。现在与 AndroidX 一起使用:

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

        【讨论】:

        • 这个答案是错误的。您应该使用 ViewModelProvider(viewModelStoreOwner, factory).get(YourVideoModel::class.java) 否则您的 onCleared() 将无法正常工作,并且 ViewModel 不会在配置更改时保留。 不要使用这个答案。
        【解决方案11】:

        直接使用 ViewModelProvider 而不是文档中提到的用户 ViewModelProviders.of()。

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

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

        【讨论】:

          【解决方案12】:

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

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

          使用以下代码:

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

          并尽快返回阅读!

          【讨论】:

            【解决方案13】:

            我正在使用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
            

            您可以像下面的示例一样初始化您的视图模型:

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

            【讨论】:

            • 感谢您的回答,但是当我使用它时,viewmodel 观察和字段数据绑定不再起作用
            • 我相信androidx.lifecycle:lifecycle-compiler 已经被androidx.lifecycle:lifecycle-common-java8 淘汰了。
            【解决方案14】:

            如果你使用 Kotlin,你可以像这样使用属性委托viewModels()

            val viewModel: YourViewModel by viewModels()
            

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

            【讨论】:

              【解决方案15】:

              使用这个:

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

              【讨论】:

              • 这不会在每次调用创建时创建新实例吗?假设像这样的 lifcyle , stop , onCreate ?
              【解决方案16】:

              你可以改用这个:

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

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

              【讨论】:

                【解决方案17】:

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

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

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

                【讨论】:

                • 这段代码是错误的,onCleared() 不会被这样调用并且你的 ViewModel 每次都会被重新创建(不会为配置更改而保留)。
                • 你能用一个例子多解释一下吗,什么可以解决我的错误?请粘贴对解释的引用或任何可以使事情更清楚的内容
                • viewModel = new ViewModelProvider(this).get(MyViewModel.class)。如果你的AndroidViewModel 没有得到Application,那么你的生命周期和活动/片段之间的版本不匹配。
                • 好的,那么调用getApplicationContext有错吗?应该只是 getContext 吗?
                • 问题是创建new ViewModelProvider.AndroidViewModelFactory( 而不是new ViewModelProvider(
                【解决方案18】:

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

                //Do not forget import it.
                import androidx.lifecycle.AndroidViewModel;
                
                ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
                

                示例用法是:

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

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

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

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

                yourViewModel = new ViewModelProvider(this).get(YourViewModel.class);
                

                因为当我使用这种方式时,我得到了以下错误消息:

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

                【讨论】:

                • 这个答案是错误的。您需要将工厂传递给 ViewModelProvider。如果您直接调用create,那么onCleared() 将无法正常工作。
                • 事实上,你只是说不要使用正确的答案。听起来您的 androidx.coreandroidx.lifecycle 依赖项之间不匹配。
                • 通常我将工厂写到 ViewModelProvider。但是,您删除了它。 ContactViewModel contactViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(ContactViewModel.class);你为什么在我的回答中删除它?你传递了错误的代码。
                【解决方案19】:

                我一直在尝试,最终在 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 以检查当前版本。

                【讨论】:

                  【解决方案20】:

                  我正在使用工厂。

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

                  【讨论】:

                    【解决方案21】:

                    当你使用匕首时,你会在构造函数中传递工厂

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

                    【讨论】:

                      【解决方案22】:

                      简单更新

                      ViewModelProviders.of(这个, provider).get(MainActivityViewModel::class.java)

                      ViewModelProvider(这个, provider).get(MainActivityViewModel::class.java)

                      【讨论】:

                        【解决方案23】:

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

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

                        //你只需要改变模型类

                        【讨论】:

                        【解决方案24】:

                        你可以这样使用:

                        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.
                        

                        【讨论】:

                          【解决方案25】:

                          我正在使用生命周期库 2.3.1 并在 build.gradle(模块级)中添加以下依赖项

                          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'
                          

                          在您的 Kotlin 代码中声明 viewModels(),如下所示:

                          import androidx.fragment.app.viewModels
                          
                          private val cartViewModel: CartViewModel by viewModels()
                          

                          【讨论】:

                            【解决方案26】:

                            试试这个...

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

                            【讨论】:

                              【解决方案27】:

                              如果你有这个实现

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

                              尝试使用 viewModel = MainViewModel()

                              【讨论】:

                              • 这不是实例化视图模型的方法。您必须为此使用 ViewModelProvider 类
                              【解决方案28】:

                              它应该这样工作

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

                              【讨论】:

                              • 虽然您的代码将实例化该类,但不会创建与 View Model 类正确响应生命周期事件所需的视图状态的连接。您需要以正确的方式实例化视图模型,以便它们响应并尊重其父母的生命周期,否则它们每次都会被重新创建为新鲜和空白。
                              • 如上所述 OP 和其他人; ViewModelProviders 类已被弃用。见:developer.android.com/reference/androidx/lifecycle/…
                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 2020-11-07
                              • 2015-04-27
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2022-07-10
                              • 1970-01-01
                              相关资源
                              最近更新 更多