【问题标题】:Architecture components ViewModel vs. savedInstanceState bundle架构组件 ViewModel 与 savedInstanceState 包
【发布时间】:2018-01-12 12:48:17
【问题描述】:

尝试了解使用 ViewModel 保留 Activity 或 Fragment 的某些状态并使用 savedInstanceState 包保存它们的区别。

在配置更改等情况下,当 Activity/Fragment 被 os 销毁时,ViewModel 实例保持活动状态,这样当 os 重新创建 Activity/Fragment 时,可以从仍然有效的 ViewModel 实例获取数据。

是否适用于最小化应用并重新打开?

做了一些测试,似乎最小化应用程序并重新打开应用程序,操作系统将重新创建活动/片段,其中 onCreate() 中的 stavedInstanceState 包不为空(调用 onSaveInstanceStae() 时保存的内容)。但是 ViewModel 已被清除,因此创建了一个没有以前数据的新实例。

这是否意味着虽然在这种情况下操作系统可以检索保存的实例状态并传递给活动/片段的 onCreate(),但是 ViewModel 必须是没有先前实例数据的新实例,或者 viewModel 需要这样做一些额外的步骤以便跨实例存储/恢复数据?

【问题讨论】:

标签: android architecture viewmodel


【解决方案1】:

可以在in this blogpost 找到一个很好的解释(以及您的问题的解决方案)。 TLDR:视图模型托管在一个持久片段中,该片段与托管活动一起重新创建。

【讨论】:

    【解决方案2】:

    如果有人仍然想了解 onSavedState 与 ViewModel 之间的区别,这里有详细的解释:

    1. onSavedInstanceState :onSavedInstance 的主要用途不是处理方向更改,而是提供一种机制来在应用程序/活动被 Android 系统销毁时检索数据。当应用程序处于后台并且 Android 系统决定终止此应用程序的示例情况,因为它需要内存用于其他一些高优先级进程,然后在这种情况下,在 Activity 被销毁之前 onSavedInstanceState 将被调用。

    2. onSavedInstanceState 只存储 Parcelable 数据,它提供了在活动重新启动时为用户恢复状态的提示。它将数据保存在系统服务器中,这是一个单独的进程。

    3. onSavedInstanceState 有数据限制。只能保存少量的 Parcelable 数据。

    ViewModel 时

    1. ViewModel 对象是应用程序进程内存的一部分,因此它能够在配置更改后继续存在。一旦进程终止,ViewModel 就会消失,所有保存的状态都将丢失。因此,当 Activity 重新启动时,ViewModel 中没有任何内容。

    2. 它可以作为重物的缓存。

    3. ViewModel 没有限制。

    重要提示:永远记住ViewModel 和SavedState 一起工作。它们不能相互替代或替代。

    【讨论】:

    • 我们可以使用 ViewModelSavedStateHandle 处理进程死亡
    【解决方案3】:

    来自:Kristin Marsicano 的书“Android 编程:大书呆子牧场指南,第 4 版”。 :

    ViewModel 与保存的实例状态

    虽然保存的实例状态存储了跨进程死亡的活动记录,但它还存储了跨配置更改的活动记录。当您第一次启动活动时,保存的实例状态 包为空。当您旋转设备时,操作系统会在您的活动上调用 onSaveInstanceState(Bundle)。然后,操作系统将您存储在捆绑包中的数据传递给 onCreate(Bundle?)

    ViewModel 在您使用它来编排 Activity 的动态数据时真的很出色

    ViewModel 使跨配置更改继续下载操作变得简单。它还提供了一种简单的方法来保存在配置更改期间加载到内存中代价高昂的数据。而且,如您所见,一旦用户完成活动,ViewModel 会自动清理。

    ViewModel 在进程死亡场景中不会发光,因为它与进程及其中的所有内容一起从内存中擦除。这是保存的实例状态 占据中心位置的地方。但是保存的实例状态有其自身的局限性。由于保存的实例状态已序列化到磁盘,因此应避免存储任何大型或复杂对象。

    lifecycle-viewmodel-savedstate 是一个刚刚发布的新库,允许 ViewModels 在进程死亡时保存其状态。这应该会减轻在您的活动中使用 ViewModels保存的实例状态 的一些困难。

    使用保存的实例状态来存储重新创建 UI 状态所需的最少信息(例如,当前问题索引)。使用 ViewModel 缓存丰富的数据集,以便在配置更改时将 UI 填充到内存中,以便快速轻松地访问。

    当进程死亡后重新创建activity时,使用保存的实例状态信息来设置ViewModel,就像设置ViewModel一样和活动从未被破坏。

    在撰写本文时,还没有简单的方法可以确定在进程死亡和配置更改之后是否正在重新创建活动。为什么这很重要? ViewModel 在配置更改期间保留在内存中。因此,如果您在配置更改后使用 保存的实例状态 数据来更新 ViewModel,您就是在让您的应用程序做不必要的工作。如果工作导致用户等待或不必要地使用他们的资源(如电池),那么这种多余的工作就会有问题。

    解决此问题的一种方法是让您的 ViewModel 更智能一些。当设置 ViewModel 值可能会导致更多工作时,请先检查数据是否新鲜,然后再执行拉入和更新其余数据的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 2021-01-06
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多