【问题标题】:When is a Viewmodel's constructor called in Android?什么时候在 Android 中调用 Viewmodel 的构造函数?
【发布时间】:2021-11-24 03:13:47
【问题描述】:

我正在浏览这个代码实验室:https://developer.android.com/codelabs/android-lifecycles#6 它解释了如何在 ViewModel 中使用 SavedStateHandle 来避免进程死亡。 ViewModel 的构造函数如下:

    private SavedStateHandle mState;

    public SavedStateViewModel(SavedStateHandle savedStateHandle) {
       mState = savedStateHandle;
    }

并且viewmodel在Activity中初始化如下:

    mSavedStateViewModel = new ViewModelProvider(this).get(SavedStateViewModel.class);

什么时候调用 ViewModel 的构造函数?而Viewmodel如何获取ViewModel的savedStateHandle参数呢?

编辑:

我通过这篇博文找到了我的问题的答案: https://www.rockandnull.com/viewmodel-savedstate/

它表示如果SavedStateHandle 是我们视图模型构造函数中的唯一参数,by viewModels 委托会自动将其提供给视图模型。

然而, 如果我们有依赖注入框架(Hilt)提供的自定义参数的组合,例如:存储库,几个其他运行时参数,例如:选择的类别 ID 和 SavedStateHandle,以帮助我们在视图模型的构造函数中幸免于进程死亡 - 如何我们可以将所有这些参数提供给工厂吗?

请贴一个小例子让我理解

【问题讨论】:

    标签: android viewmodel android-lifecycle


    【解决方案1】:

    您所关注的 Codelab 是为了让您了解特定的概念,而不是 整个代码。对于您的疑问,他们没有提供任何实现,即 ViewModel 如何获取它的参数?


    概览: 由于 ViewModel 的某些内部实现,您不能直接将参数传递给 ViewModel,而是需要创建第三个类来为 ViewModel 提供参数。


    回答你的疑问:

    ViewModel 可以通过两种方法获取其参数:

    1. 非依赖注入方式: 在这里,您创建了一个扩展 ViewModelProvider.Factory 的类。在您的代码中,您可以在这里看到:
      mSavedStateViewModel = new ViewModelProvider(this).get(SavedStateViewModel.class);
    

    这里创建了一个默认类,其中不传递任何参数。这样做是为了初始化,这是代码实验室中给出的表达需求的不完整方式。您可以通过这篇文章获得关于同一概念的大量知识:

    https://medium.com/koderlabs/viewmodel-with-viewmodelprovider-factory-the-creator-of-viewmodel-8fabfec1aa4f

    1. 依赖注入方式: 现在,如果您了解 DI 框架 Hilt,这是实现 ViewModelProviders 的最简单方法。在这里,您只需使用 @ViewModelInject 注释您的 ViewModel 即可。后台中的 DI 框架将创建一个 ViewModelFactory 而不是您这样做。这是您如何使用 Hilt 向 ViewModel 提供参数的示例代码:
    
    class SampleViewModel @ViewModelInject constructor(
                         @Assisted private val savedStateHandle: SavedStateHandle) : ViewModel() { }
    

    【讨论】:

    • 我已经从 codelab 调试了应用程序。即使我没有通过任何工厂,它的构造函数也会被调用。这怎么可能?谁将 SavedStateHandle 传递给构造函数?
    • 你能分享应用程序的链接吗?您是否在 Android Studio 上本地运行该应用程序?因为codelab中提到的代码的github链接提到了一些用例及其解决方案,所以没有像完整应用程序那样完整的解决方案
    • 您可以从这里下载源代码:developer.android.com/codelabs/android-lifecycles#1
    • 另外请查看问题的编辑部分
    • 很高兴您得到答案。
    猜你喜欢
    • 1970-01-01
    • 2013-06-21
    • 2010-11-29
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    相关资源
    最近更新 更多