架构组件 ViewModel 与 savedInstanceState bundle 对比

20

尝试理解使用ViewModel来保持一些活动或片段的状态与使用savedInstanceState bundle保存它们之间的区别。

对于像配置更改这样的情况,似乎ViewModel实例在活动/碎片被操作系统销毁时仍然保持活动状态,因此当操作系统重新创建活动/碎片时,可以从仍然有效的ViewModel实例获取数据。

这适用于最小化应用程序并重新打开吗?

进行了一些测试,似乎将应用程序最小化并重新打开时,操作系统将在onCreate()中使用不为空的stavedInstanceState bundle重新创建活动/碎片(无论何时调用onSaveInstanceStae()都会保存)。但ViewModel已被清除,因此将创建一个新实例,没有先前实例的数据。

这是否意味着尽管在此情况下操作系统可以检索保存的实例状态并传递给活动/碎片的onCreate(),但ViewModel必须是一个新实例,没有以前实例的数据,还是viewModel需要执行一些额外的步骤才能在实例之间存储/恢复数据?


官方文档已经回答了你的问题:https://developer.android.com/topic/libraries/architecture/viewmodel.html#viewmodel_vs_savedinstancestate - vlazzle
点击此处查看更多信息:https://medium.com/google-developers/viewmodels-persistence-onsaveinstancestate-restoring-ui-state-and-loaders-fc7cc4a6c090 - Pravin Divraniya
你所说的“最小化”应该是指按下主页按钮将应用程序放到后台,对吗? - IgorGanapolsky
3个回答

11
如果有人仍然想要了解onSavedState和ViewModel之间的区别,这里有详细的解释:
  1. onSavedInstanceState:onSavedInstanceState的主要用途不是处理方向更改,而是提供一种机制,在应用/活动被Android系统销毁时检索数据。例如,当应用程序在后台运行且Android系统决定将其杀死以为某些其他高优先级进程腾出内存时,在活动被销毁之前将调用onSavedInstanceState。
  2. onSavedInstanceState仅存储Parcelable数据,该数据提供提示以在活动重新启动时恢复用户状态。它将数据保存在系统服务器中,这是一个单独的进程。
  3. onSavedInstanceState具有数据限制。只能保存少量的Parcelable数据。
对于ViewModel
  1. ViewModel对象是应用程序进程内存的一部分,因此它能够在配置更改后继续存在。一旦进程死亡,ViewModel就会消失,并且所有保存的状态都将丢失。因此,当活动重新启动时,ViewModel中什么也没有。
  2. 它作为重型对象的缓存。
  3. ViewModel没有任何限制。
重要提示:始终记住ViewModel和SavedState一起使用。它们不是彼此的替代品或替代品。

enter image description here


1
我们可以使用 ViewModelSavedStateHandle 来处理进程死亡。 - IgorGanapolsky

5
在这篇博客文章中,可以找到一个很好的解释(和你问题的解决方案)。简而言之,ViewModel 托管在一个持续存在的片段中,该片段与托管活动一起重建。请参阅此博客文章了解更多信息。

4

来自Kristin Marsicano的书籍“Android Programming: The Big Nerd Ranch Guide, 4th Edition.”:

ViewModel vs Saved Instance State

保存实例状态(Saved Instance State)不仅可以在进程死亡时存储活动记录,还可以在配置更改时存储活动记录。当你首次启动活动时,保存实例状态束为空。当你旋转设备时,操作系统会调用你的活动的onSaveInstanceState(Bundle)方法。然后,操作系统将你在束内存储的数据传递给onCreate(Bundle?)

ViewModel在为活动编排动态数据时表现得非常出色。

ViewModel使得跨配置更改继续下载操作变得简单。它还提供了一种简单的方法来在配置更改期间保留昂贵的加载数据。而且,正如你所见,用户完成活动后,ViewModel会自动清理。

ViewModel在进程死亡情况下并不高效,因为它会与进程以及其中的所有内容一起从内存中删除。这就是保存实例状态成为主角的地方。但是保存实例状态也有其限制。由于保存实例状态被序列化到磁盘,所以应避免储存任何大型或复杂的对象。

lifecycle-viewmodel-savedstate是一个新库,刚刚发布,可以使ViewModels在进程死亡时保存它们的状态。这应该能够减轻使用ViewModelssaved instance state一起的困难。

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

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

截至撰写本文时,没有简单的方法确定活动是否正在进程死亡后重新创建还是进行配置更改。为什么这很重要?ViewModel在配置更改期间会保留在内存中。因此,如果你在配置更改后使用saved instance state数据来更新ViewModel,则会导致你的应用程序做出不必要的工作。如果这项工作导致用户等待或不必要地使用他们的资源(例如电池),则会造成问题。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接