存活配置更改机制的工作原理是如何的?

huangapple go评论83阅读模式
英文:

how does surviving configuration changes mechanisms work?

问题

我有三个类似的问题,涉及在配置更改时保留配置的方法。我知道有三种方式可以在配置更改时保留对象,但我不清楚它们的内部原理。

  1. 覆盖 onSaveInstanceState 方法。我知道它会将数据放入 bundle 中。但它是如何在配置更改时保持数据的?实际上 bundle 是什么?它是否属于 Activity?在应用程序中我们只有一个 bundle 吗?(我知道我们可以创建不同的实例,但是当我们使用 putExtraonSaveInstanceState 或其他任何方法存储数据时,它们是否被放在同一个位置?)

  2. 使用 onRetainNonConfigurationInstance()getLastNonConfigurationInstance() 方法。这用于在配置更改时保留 viewModelStore。那么它是如何工作的,数据放在哪里呢?(我知道这些方法已被弃用)

  3. 保留的(Holder)Fragment 和片段中的 setRatinInstance() 方法。同样的问题(我认为 Activity 对于这一点只是使用了 onRetainNonConfigurationInstance(),如果我有错误,请纠正我)

我在互联网和 StackOverflow 上搜索过这个问题,但是没有找到相关信息。我也尝试阅读实际的代码,但没有成功!由于这些问题相关,我想把它们都放在一个问题里,希望这样做没问题。

英文:

I have three similar questions about surviving configuration changes. I know three ways to retain objects across configuration changes but I don't know how they work under the hood.

  1. Overriding onSaveInstanceState. I know it puts the data in the bundle. but how does it survive configuration changes? what really bundle is? does it belong to activity? do we have only one bundle in the app? (I know we can make different instances but when we put our data with putExtra or onSaveInstanceState or any other method, are they going to the same place?)

  2. Using onRetainNonConfigurationInstance() and getLastNonConfigurationInstance(). this is used to retain viewModelStore across configuration changes. so how it works and where does it put the data?(I know about deprication)

  3. Retained(Holder) Fragment and setRatinInstance() method in the fragment. the same question(I think the activity just uses the onRetainNonConfigurationInstance() for this, correct me if I'm wrong)

I searched the net and StackOverflow for this but I couldn't find anything. I also tried to go through the actual codes, but no luck!
since the questions are relevant I thought I put them all in one question. hope it's fine.

答案1

得分: 3

> 覆盖 onSaveInstanceState。我知道它将数据放入 bundle 中。但它如何在配置更改后保留?bundle 到底是什么?它属于 Activity 吗?我们在应用程序中只有一个 bundle 吗?(我知道我们可以创建不同的实例,但当我们使用 putExtra、onSaveInstanceState 或任何其他方法放入数据时,它们是否进入相同的位置?)

那不算真正的“跨配置更改保留”,更多地是“在进程级持久性保存”,然后在配置更改时重新使用。之所以不认为它是“保留”,是因为该对象被封装为 Parcelable,然后在恢复时创建副本。

无论如何,ActivityRecord 有一个 bundle,每个任务堆栈都有自己的 ActivityRecords,并且当进程死亡发生时,系统会保存和恢复任务堆栈。这种机制恰好也“处理配置更改”。

Intent.putExtra 的工作方式非常相似,是的。

> 使用 onRetainNonConfigurationInstance() 和 getLastNonConfigurationInstance()。这用于在配置更改时保留 viewModelStore。它是如何工作的,数据放在哪里?(我知道已经不推荐使用了)

onSaveInstanceState 不同,这实际上是一个仅在配置更改时保留对象的操作系统级回调。以前有 onRetainCustomNonConfigurationInstance/getLastCustomNonConfigurationInstance,但已被弃用,代之以 ViewModel,因为 ViewModel 被认为是“唯一标准”的在配置更改时保留的方法。在内部,实际上就是 viewModelStoreonRetainNonConfigurationInstance(它是一个映射)。

> 保留(Holder)片段和片段中的 setRetainInstance() 方法。同样的问题(我认为 Activity 只是在这种情况下使用了 onRetainNonConfigurationInstance(),如果我错了,请纠正我)

是的,尽管不幸的是,在最新的 Jetpack 版本中已经弃用了这一方法(为了简化片段及其生命周期的交互)。片段管理器被保留为非配置,保留的片段也随之保留,使用的是 FragmentActivityonRetainNonConfigurationInstance()(我认为现在称为 FragmentManagerViewModel)。

非配置实例保留在ActivityClientRecord中,这些实例不被ActivityStack持久化。

希望这些足够解答您的问题。

英文:

> Overriding onSaveInstanceState. I know it puts the data in the bundle. but how does it survive configuration changes? what really bundle is? does it belong to activity? do we have only one bundle in the app? (I know we can make different instances but when we put our data with putExtra or onSaveInstanceState or any other method, are they going to the same place?)

That's not really "retention across config change", that's more-so "saving at process-level durability" which is then re-used for config changes. The reason why I wouldn't consider it "retention" is because the object is parcelled as Parcelable, then a copy is created on restoration.

Anyway, the ActivityRecord has a bundle, each task stack has its own ActivityRecords, and the task stack is saved and restored by the system when process death happens. This mechanism just happens to "also handle config change".

Intent.putExtra works very similarly, yes.

> Using onRetainNonConfigurationInstance() and getLastNonConfigurationInstance(). this is used to retain viewModelStore across configuration changes. so how it works and where does it put the data?(I know about deprication)

Unlike onSaveInstanceState, this actually is an OS-level callback that only serves to retain an object across config changes. There used to be onRetainCustomNonConfigurationInstance/getLastCustomNonConfigurationInstance, but it was deprecated in favor of ViewModel, as ViewModel is intended to be the "one and only standard" way of retaining across config change. Internally, it's just onRetainNonConfigurationInstance of the viewModelStore (which is a map), though.

> Retained(Holder) Fragment and setRetainInstance() method in the fragment. the same question(I think the activity just uses the onRetainNonConfigurationInstance() for this, correct me if I'm wrong)

Yes, although unfortunately that is also deprecated in the latest Jetpack Fragments versions (in order to simplify the interaction of fragments and their lifecycle). The fragment manager is retained as non-config, and the retained fragments are retained along with it, using onRetainNonConfigurationInstance() of the FragmentActivity (I think now it's called FragmentManagerViewModel).

Non-configuration instances are kept in the ActivityClientRecord which are not persisted by the ActivityStack.

Hope that covers enough.

huangapple
  • 本文由 发表于 2020年10月8日 07:40:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/64253762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定