简体   繁体   English

架构组件 ViewModel vs. savedInstanceState 包

[英]Architecture components ViewModel vs. savedInstanceState bundle

Trying to understand what is the difference with using the ViewModel to keep some of the state of the activity or fragment, and saving them with the savedInstanceState bundle.试图了解使用 ViewModel 保留 Activity 或 Fragment 的某些状态并使用 savedInstanceState 包保存它们有什么区别。

Got a impression that the ViewModel instance is kept alive when the activity/fragment is destroyed by os in the case like configuration change so that when os recreate the activity/fragment could get the data from the ViewModel instance which is still valid.印象中,在配置更改等情况下,当 os 销毁活动/片段时,ViewModel 实例会保持活动状态,以便在 os 重新创建活动/片段时,可以从仍然有效的 ViewModel 实例中获取数据。

Does it apply to minimize the app and re-open it?它是否适用于最小化应用程序并重新打开它?

Did some test, seems minimize the app and re-open the app, the os will recreate the activity/fragment with the stavedInstanceState bundle in the onCreate() not null (whatever is saved when the onSaveInstanceStae() is called).做了一些测试,似乎最小化应用程序并重新打开应用程序,操作系统将使用 onCreate() 中的 stavedInstanceState 包重新创建活动/片段,而不是 null(调用 onSaveInstanceStae() 时保存的内容)。 But the ViewModel has been cleared so a new instance is created without previous ones data.但是 ViewModel 已被清除,因此创建了一个没有以前数据的新实例。

Does it it mean although is in this case the os can retrieve the saved instance state and pass to activity/fragment's onCreate(), but the ViewModel has to be a new instance without previous instance's data, or the viewModel needs do to some extra step inorder to store/restore the data cross the instances?这是否意味着虽然在这种情况下操作系统可以检索保存的实例状态并传递给活动/片段的 onCreate(),但是 ViewModel 必须是一个没有先前实例数据的新实例,或者 viewModel 需要做一些额外的步骤为了跨实例存储/恢复数据?

If someone is still looking to understand difference between onSavedState vs ViewModel here is the detailed explanation:如果有人仍然想了解 onSavedState 与 ViewModel 之间的区别,这里是详细解释:

  1. onSavedInstanceState : Primary usage of onSavedInstance was not to handle orientation change but to provide a mechanism to retrieve data if app/activity is destroyed by Android System. onSavedInstanceState : onSavedInstance 的主要用途不是处理方向更改,而是提供一种机制,在 Android 系统销毁应用程序/活动时检索数据。 Example case when app is in background and Android system decide to kill this as it needs memory for some other high priority process then in this case before activity is destroyed onSavedInstanceState will be called.当应用程序处于后台并且 Android 系统决定终止它时的示例情况,因为它需要一些其他高优先级进程的内存,然后在这种情况下,在活动被销毁之前 onSavedInstanceState 将被调用。

  2. onSavedInstanceState only stores the Parcelable data, that provides hint to restore the state for the user when activity restarts. onSavedInstanceState 只存储 Parcelable 数据,它提供提示以在 Activity 重新启动时为用户恢复状态。 It saves data in System server that is a separate process.它将数据保存在作为单独进程的系统服务器中。

  3. onSavedInstanceState has data limit. onSavedInstanceState 有数据限制。 Only small amount of Parcelable data can be saved.只能保存少量 Parcelable 数据。

While for ViewModel而对于 ViewModel

  1. ViewModel object is part of Applications process memory and hence it is able to survive configuration changes. ViewModel 对象是应用程序进程内存的一部分,因此它能够承受配置更改。 Once a process dies, ViewModel goes away and all the saved state will be lost.一旦进程终止,ViewModel 就会消失并且所有保存的状态都将丢失。 Hence when activity restarts, ViewModel has nothing in it.因此,当活动重新启动时,ViewModel 中没有任何内容。

  2. It works as a cache for heavy objects.它用作重物的缓存。

  3. There are no restrictions in ViewModel. ViewModel 中没有限制。

Important : Always remember ViewModel and SavedState work together .重要提示:永远记住ViewModel 和 SavedState 一起工作 They are not replacement or alternative to each other.它们不是彼此的替代品或替代品。

在此处输入图片说明

A good explanation (and a solution to your problem) can be found in this blogpost .可以在这篇博文中找到一个很好的解释(以及您问题的解决方案)。 TLDR: the viewmodel is hosted inside a persisted fragment, which gets recreated together with the hosting activity. TLDR:视图模型托管在持久片段中,该片段与托管活动一起重新创建。

From: Kristin Marsicano Book “Android Programming: The Big Nerd Ranch Guide, 4th Edition.”来自:Kristin Marsicano 书籍“Android 编程:大书呆子牧场指南,第 4 版”。 :

ViewModel vs Saved Instance State ViewModel 与保存的实例状态

While saved instance state stores an activity record across process death, it also stores an activity record across a configuration change.虽然保存的实例状态存储了跨进程死亡的活动记录,但它还存储了跨配置更改的活动记录。 When you first launch the activity, the saved instance state bundle is null.首次启动活动时,保存的实例状态包为空。 When you rotate the device, the OS calls onSaveInstanceState(Bundle) on your activity.当您旋转设备时,操作系统会在您的活动上调用onSaveInstanceState(Bundle) The OS then passes the data you stashed in the bundle to onCreate(Bundle?) .然后,操作系统将您藏在包中的数据传递给onCreate(Bundle?)

ViewModel really shines when you use it to orchestrate dynamic data for the activity当您使用ViewModel为活动编排动态数据时,它真的很出色

ViewModel makes continuing a download operation across a configuration change simple. ViewModel使跨配置更改继续下载操作变得简单。 It also offers an easy way to keep data that was expensive to load in memory across a configuration change.它还提供了一种简单的方法来保存在配置更改期间加载到内存中的数据开销很大。 And, as you have seen, ViewModel gets cleaned up automatically once the user finishes the activity.而且,如您所见,一旦用户完成活动, ViewModel就会自动清理。

ViewModel does not shine in the process death scenario since it gets wiped away from memory along with the process and everything in it. ViewModel不会在进程死亡场景中发光,因为它会与进程及其中的所有内容一起从内存中擦除。 This is where saved instance state takes center stage.这是保存的实例状态占据中心位置的地方。 But saved instance state has its own limitations.但是保存的实例状态有其自身的局限性。 Since saved instance state is serialized to disk, you should avoid stashing any large or complex objects.由于保存的实例状态被序列化到磁盘,你应该避免隐藏任何大型或复杂的对象。

lifecycle-viewmodel-savedstate is a new library that was just released to allow ViewModels to save their state across process death. Lifecycle-viewmodel-savedstate是一个刚刚发布的新库,它允许ViewModel在进程死亡时保存它们的状态。 This should alleviate some of the difficulties of using ViewModels alongside saved instance state from your activities.这应该可以减轻将ViewModel与活动中保存的实例状态一起使用的一些困难。

Use saved instance state to store the minimal amount of information necessary to re-create the UI state (for example, the current question index).使用保存的实例状态来存储重新创建 UI 状态所需的最少信息(例如,当前问题索引)。 Use ViewModel to cache the rich set of data needed to populate the UI in memory across configuration changes for quick and easy access.使用ViewModel缓存在配置更改时在内存中填充 UI 所需的丰富数据集,以便快速轻松地访问。

When the activity is re-created after process death, use the saved instance state information to set up the ViewModel as if the ViewModel and activity were never destroyed.在进程死亡后重新创建活动时,使用保存的实例状态信息来设置ViewModel ,就好像ViewModel和活动从未被销毁一样。

As of this writing, there is no easy way to determine whether an activity is being re-created after process death versus a configuration change.在撰写本文时,没有简单的方法可以确定是否在进程死亡与配置更改后重新创建活动。 Why does this matter?为什么这很重要? A ViewModel stays in memory during a configuration change. ViewModel在配置更改期间保留在内存中。 So if you use the saved instance state data to update the ViewModel after the configuration change, you are making your app do unnecessary work.因此,如果您在配置更改后使用保存的实例状态数据来更新ViewModel ,那么您正在使您的应用程序执行不必要的工作。 If the work causes the user to wait or uses their resources (like battery) unnecessarily, this redundant work is problematic.如果工作导致用户等待或不必要地使用他们的资源(如电池),则这种冗余工作是有问题的。

One way to fix this problem is to make your ViewModel a little smarter.解决此问题的一种方法是使您的ViewModel更智能一些。 When setting a ViewModel value might result in more work, first check whether the data is fresh before doing the work to pull in and update the rest of the data.当设置ViewModel值可能会导致更多工作时,请先检查数据是否新鲜,然后再进行拉入和更新其余数据的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM