【问题标题】:As ViewModelProviders.of() is deprecated, how should I create object of ViewModel?由于不推荐使用 ViewModelProviders.of(),我应该如何创建 ViewModel 的对象?
【发布时间】:2019-12-23 08:58:51
【问题描述】:

我一直在尝试在 Activity 中创建 ViewModel 的对象,但不推荐使用 ViewModelProviders 那么创建 ViewModel 对象的替代方法是什么。

【问题讨论】:

    标签: android viewmodel


    【解决方案1】:

    接下来几个月的简单选择是坚持使用稳定版或测试版。 ViewModelProviders 仅从 2.2.0 开始被弃用,目前在 alpha03 版本中。

    当您确实迁移到 2.2.0 或更高版本的生命周期依赖项时,您的选择取决于您的语言:

    • 如果您使用 Java,请使用 ViewModelProvider() 构造函数,传入您的活动或片段

    • 如果你使用 Kotlin,应该有一个 by viewModels() 属性委托,虽然我在源代码中没有找到它...

    【讨论】:

    • 要使用by viewModels()你需要添加这个依赖implementation 'androidx.fragment:fragment-ktx:1.2.0'
    • @CommonsWare 我想我们应该使用以下依赖项来实例化视图模型 对于片段实现 'androidx.fragment:fragment-ktx:xxx' 对于活动实现 "androidx.activity:activity-ktx:xxx"
    • @VikashKumarTiwari:是的,我相信by viewModels()by activityViewModels() 是在fragment-ktxactivity-ktx 工件中定义的。
    • @CommonsWare 根据 2020 年 1 月 22 日的最新版本 1.2.0 版本,viewModels() 和 activityViewModels() 存在于以下依赖项实现“androidx.fragment:fragment-ktx:1.2.0”中此外,viewModels() 将用于活动和片段中的视图模型初始化。但是通过activityViewModels()只能在fragment中使用来获取父activity的viewmodel。此外,在使用实现“androidx.activity:activity-ktx:x.x.x”时,我们只能在activity中通过viewModels()访问,而不会在fragment中访问。
    【解决方案2】:

    ViewModelProviders.of() 已被弃用。您可以将 Fragment 或 FragmentActivity 传递给新的 ViewModelProvider(ViewModelStoreOwner) 构造函数以实现相同的功能。 (aosp/1009889)

    Please click here to see the solution

    【讨论】:

      【解决方案3】:

      如果您使用的是 Kotlin,而不是:

      private lateinit var viewModel: EntityGridViewModel
      
      [...]
      
      // Deprecated
      viewModel = ViewModelProviders.of(this).get(EntityGridViewModel::class.java)
      

      你可以使用更好的:

      private val viewModel: EntityGridViewModel by viewModels()
      

      【讨论】:

      • 问题是关于你所提议的替代方案
      • 如何将工厂传递给 'viewModels()' 委托???
      【解决方案4】:

      简单替换:

      这个:

      boardViewModel = ViewModelProviders.of(this).get(BoardViewModel::class.java)
      

      有了这个:

      boardViewModel = ViewModelProvider(this).get(BoardViewModel::class.java)
      

      【讨论】:

      • 在 Java 中:“boardViewModel = new ViewModelProvider(this).get(BoardViewModel.class)”
      • boardViewModel = ViewModelProvider(this).get("model", BoardViewModel::class.java) 仅在最新版本中为我编译。
      • 对我来说 .get(UserViewModel::class.java) 有红色下划线,出于某种原因,它说“Type parameter bound for T in operator fun get (modelClass: Class ) : T 不满足:推断类型 UserViewModel! 不是 ViewModel 的子类型!"。
      • this 代表什么?
      【解决方案5】:

      ViewModelProviders.of() 已被弃用。

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

      Java

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

      科特林

      mainActivityViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
      

      【讨论】:

      • 这在我的案例中起到了作用。谢谢!很高兴提到我不得不将一些红色的this 更改为getViewLifecycleOwner() 以避免警告。
      【解决方案6】:

      这次 Gradle 升级给我带来了问题。

      来自

      implementation 'androidx.core:core:1.1.0'
      

      implementation 'androidx.core:core:1.2.0'
      

      在主要活动 Java/Kotlin 文件中

      这个导入语句

      import androidx.lifecycle.ViewModelProviders
      

      不得不改成

      import androidx.lifecycle.ViewModelProvider
      

      这个 KOTLIN viewModel 语句

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

      不得不改成

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

      在 JAVA 中

      这行JAVA代码

      mViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
      

      不得不改成

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

      然后这一切都对我有用。

      基于: 为我造成问题的步骤概述

      【讨论】:

      • 这是。迄今为止最清楚和最好的答案。
      • 是的,伙计!最好的解决方案是这个,它确实解决了我的问题。
      • 嘿,需要Application作为构造函数参数的AndroidViewModel呢?
      【解决方案7】:

      此类已弃用。 直接使用 ViewModelProvider 的构造函数。 here

      所以不要使用这个

      ViewModelProviders.of(this).get(MyViewModel.class); - deprecated
      

      使用这个

      new ViewModelProvider(this).get(MyViewModel.class); - correct
      

      【讨论】:

        【解决方案8】:

        我们现在应该使用 ViewModelProvider 构造函数,而不是 ViewModelProviders,它有三个:

        public ViewModelProvider(ViewModelStoreOwner owner)
        public ViewModelProvider(ViewModelStoreOwner owner, Factory factory)
        public ViewModelProvider(ViewModelStore store, Factory factory)
        

        1. 如果您没有使用ViewModelProvider.Factorypass additional arguments 到您的ViewModel,您可以使用第一个。所以:

        viewModel = ViewModelProviders.of(this).get(YourViewModel.class);
        

        可以替换为:

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

        AppCompatActivity 和不同类型的Fragments 是ViewModelStoreOwner 的间接子类(请参阅其已知子类here 的完整列表),因此您可以在此构造函数中使用它们。

        2.但是如果你使用ViewModelProvider.Factory,你应该使用第二个或第三个构造函数:

        viewModel = ViewModelProviders.of(this, viewModelFactory).get(YourViewModel.class);
        

        可以替换为:

        viewModel = new ViewModelProvider(this, viewModelFactory).get(YouViewModel.class);
        

        或基于documentationViewModelStore

        使用 ViewModelStoreOwner.getViewModelStore() 检索一个 Activity 和 Fragment 的 ViewModelStore。

        viewModel = new ViewModelProvider(getViewModelStore(), viewModelFactory).get(YourViewModel.class);
        

        【讨论】:

        • 这是最好的答案
        【解决方案9】:

        由于 ViewModelProviders 已被弃用。您现在可以直接使用 ViewModelProvider 构造函数。更多使用方法请查看here

        【讨论】:

          【解决方案10】:

          此代码适用于我

          private lateinit var viewModel: MainViewModel
          viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MainViewModel::class.java)
          

          【讨论】:

            【解决方案11】:

            您可以在应用程序build.gradle中添加以下依赖项:

            //for activity
            implementation "androidx.activity:activity-ktx:1.2.2"
            //for fragment
            implementation "androidx.fragment:fragment-ktx:1.3.2"
            

            然后像下面这样使用:

            private val viewmodel: YOUR_VIEW_MODEL_CLASS_NAME by viewModels()
            

            如果你有自己的视图模型工厂,那么

              private val viewmodel: YOUR_VIEW_MODEL_CLASS_NAME by viewModels { YOUR_VIEW_MODEL_FACTORY }
            

            【讨论】:

              【解决方案12】:

              对于java

              简单地替换这个:

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

              有了这个:

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

              如果你有自己的工厂,那么

              viewModel = 
              ViewModelProvider(this,YOUR_FACTORY).get(YOUR_VIEW_MODEL::class.java)
              

              对于kotlin: 有一种更好的方法可以做到这一点。您可以在应用程序build.gradle 中添加以下依赖项:

              //for activity
              implementation "androidx.activity:activity-ktx:1.3.0-alpha06"
              //for fragment
              implementation "androidx.fragment:fragment-ktx:1.3.2"
              

              然后像下面这样访问视图模型:

              private val viewmodel: YOUR_VIEW_MODEL by viewModels()
              

              如果你有自己的视图模型工厂,那么

                private val viewmodel: YOUR_VIEW_MODEL by viewModels { YOUR_VIEW_MODEL_FACTORY }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2018-12-10
                • 2019-04-06
                • 1970-01-01
                • 1970-01-01
                • 2013-05-20
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多