【问题标题】:Saving activity's state with onSaveInstanceState() and ViewModel使用 onSaveInstanceState() 和 ViewModel 保存活动的状态
【发布时间】:2019-07-17 08:22:18
【问题描述】:

阅读本文后,我对 ViewModel 有一些疑问:

https://developer.android.com/topic/libraries/architecture/saving-states

这里说您应该结合使用ViewModel 来进行配置更改(如屏幕旋转),并使用onSaveInstanceState() 来处理活动被销毁然后重新创建以保存 UI 的所有其他情况状态。

我的问题是我们如何知道在调用onCreate(Bundle) 时恢复状态的方式 - 我应该使用 ViewModel 还是应该使用接收到的包作为参数?当配置发生变化时,onSaveInstanceState()也会被调用,显然onCreate()总是被调用。

如果我只从 ViewModel 恢复状态,它不会始终保留正确的数据(因为活动可能由于配置更改以外的其他原因而被破坏)。如果我只使用我保存在onSaveInstanceState() 中的捆绑包,那我为什么要使用ViewModel 开头呢?

【问题讨论】:

    标签: android android-activity persistence android-viewmodel android-mvvm


    【解决方案1】:

    我认为将这些来源视为一个链条很好。 您有 2 个数据源 - ViewModel,速度更快但寿命较短,保存的实例状态较慢但寿命更长。

    规则很简单 - 尝试使用您的 ViewModel,如果未填充,请使用来自 onSaveInstanceState() 的包。

    当您在 onCreate() 中执行 val model = ViewModelProviders.of(this).get(MyViewModel::class.java) 时,您可以检查是否获得了新的 viewModel 实例。然后,如果它是一个新实例(即它的数据字段为空),您可以从您的包中获取一些基本数据,如内容 ID,并根据该 ID 从后端或数据库中获取数据,用它填充您的新 ViewModel 并然后从 ViewModel 填充您的活动(如果您使用的是 LiveData,这将非常自然)。

    下次调用 onCreate 时,您重复该过程,从 ViewModel 填充您的活动,或者使用 Bundle 中的数据填充您的 ViewModel,然后从您的 ViewModel 填充您的活动。

    更新: 实际上,官方docs 中描述了非常相似的方法。唯一的区别是您将捆绑包传递给 ViewModel 并由它决定是否需要获取数据,我没有具体说明这种机制。

    【讨论】:

    • 如果我在 ViewModel 中拥有的只是初始化为默认值的原语怎么办?我无法判断这是因为该实例是一个新实例,还是这些只是正确的值。无论如何,总的来说,您的建议听起来像是一种解决方法..
    • 好吧,在这种特殊情况下,您需要实现一些字段来指示您的 ViewModel 不是新创建的,或者将一些数据添加到您的状态包并使用它。如果你只有一堆原语要保存,你不会从使用 ViewModel 中得到太多,在这种情况下,只需实现实例状态并使用它。 ViewModel 可帮助您保留复杂的下载数据或用户生成的数据。
    • 还要检查答案更新,它链接到官方方法。
    • 所以据我了解,它也只是说您应该检查所需的数据是否已经存在.. 是否有某种系统标志告诉您您在 onCreate 中的原因?或者可能是一个标志,告诉您 ViewModel 是否刚刚创建?
    • 我认为当您第一次使用 ViewModelProviders 创建 ViewModel 时,框架不会在 ViewModel 上调用任何参数构造函数,因此您可以将其用作 ViewModel 是新的指标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    相关资源
    最近更新 更多