架构组件 ViewModel 与 savedInstanceState 包

Architecture components ViewModel vs. savedInstanceState bundle

试图了解使用 ViewModel 保留 activity 或片段的某些状态并使用 savedInstanceState 包保存它们的区别。

我的印象是当 activity/fragment 被 os 销毁时 ViewModel 实例在配置更改等情况下保持活动状态,因此当 os 重新创建 activity/fragment 可以从仍然有效的 ViewModel 实例中获取数据。

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

做了一些测试,似乎最小化应用程序并重新打开应用程序,os 将重新创建 activity/fragment,其中 onCreate() 中的 stavedInstanceState 包不为空(无论什么时候保存onSaveInstanceStae() 被调用)。但是 ViewModel 已被清除,因此创建了一个没有以前数据的新实例。

这是否意味着虽然在这种情况下 os 可以检索保存的实例状态并传递给 activity/fragment 的 onCreate(),但是 ViewModel 必须是一个没有以前实例的数据,或者 viewModel 需要做一些额外的步骤才能 store/restore 数据 cros 实例?

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

一起重新创建

如果有人仍在寻找了解 onSavedState 与 ViewModel 之间的区别,请查看详细说明:

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

  2. onSavedInstanceState 只存储 Parcelable 数据,当 activity 重启时为用户提供恢复状态的提示。它将数据保存在作为单独进程的系统服务器中。

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

而对于 ViewModel

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

  2. 它用作重对象的缓存。

  3. ViewModel 中没有任何限制。

重要:永远记住ViewModel 和SavedState 一起工作。它们不是彼此的替代品或替代品。

来自:Kristin Marsicano 的书“Android 编程:Big Nerd Ranch 指南,第 4 版。” :

ViewModel 与保存的实例状态

虽然 保存的实例状态 在进程死亡时存储 activity 记录,但它也会在配置更改时存储 activity 记录。首次启动 activity 时,saved instance state 包为空。当您旋转设备时,OS 会在您的 activity 上调用 onSaveInstanceState(Bundle)。 OS 然后将您存储在包中的数据传递给 onCreate(Bundle?).

ViewModel 当您使用它为 activity

编排动态数据时,它真的很闪耀

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

ViewModel 就会自动清理

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

lifecycle-viewmodel-savedstate 是一个刚刚发布的新库,允许 ViewModels 在进程终止时保存它们的状态。这应该可以减轻在活动中使用 ViewModelssaved instance state 的一些困难。

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

进程死亡后重新创建activity时,使用保存的实例状态信息设置ViewModel 就好像 ViewModel 和 activity 从未被销毁过。

在撰写本文时,没有简单的方法来确定 activity 是在进程终止后还是在配置更改后重新创建。为什么这很重要? ViewModel 在配置更改期间保留在内存中。因此,如果您在配置更改后使用 saved instance state 数据来更新 ViewModel,您会让您的应用执行不必要的工作。如果工作导致用户等待或不必要地使用他们的资源(如电池),则这种冗余工作是有问题的。

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