358

从文档开始:

公共无效 setRetainInstance(布尔保留)

控制是否在 Activity 重新创建期间(例如从配置更改)保留片段实例。这只能与不在后台堆栈中的片段一起使用。如果设置,片段生命周期将在重新创建活动时略有不同:

  • onDestroy() 将不会被调用(但 onDetach() 仍然会被调用,因为片段正在与其当前活动分离)。
  • onCreate(Bundle) 不会被调用,因为片段没有被重新创建。
  • onAttach(Activity) 和 onActivityCreated(Bundle) 仍将被调用。

我有一些疑问:

  • 片段是否也保留其视图,或者会在配置更改时重新创建?“保留”究竟是什么意思?

  • 当用户离开activity时,fragment会被销毁吗?

  • 为什么它不适用于后堆栈上的片段?

  • 在哪些用例中使用此方法有意义?

4

5 回答 5

361

首先,查看关于保留片段的帖子。它可能会有所帮助。

现在回答你的问题:

片段是否还保留其视图状态,或者会在配置更改时重新创建 - 究竟什么是“保留”?

是的,Fragment的状态将在配置更改期间保留。具体来说,“保留”意味着片段不会在配置更改时被销毁。也就是说,即使配置更改导致底层被破坏,Fragment也会保留。Activity

当用户离开activity时,fragment会被销毁吗?

就像Activitys一样,Fragments可能会在内存资源不足的时候被系统销毁。无论您是否让您的片段在配置更改中保留其实例状态,都不会影响系统是否会在Fragment您离开Activity. 如果您离开Activity(即按主页按钮),Fragments 可能会或可能不会被破坏。如果您Activity通过按后退按钮离开 (因此,调用finish()并有效地销毁Activity),所有Activity附加Fragment的 s 也将被销毁。

为什么它不适用于后堆栈上的片段?

不支持它可能有多种原因,但对我来说最明显的原因是Activity持有对 的引用FragmentManager,并且FragmentManager管理后台堆栈。也就是说,无论您是否选择保留您Fragment的 s ,Activity(以及因此FragmentManager的 后堆栈)都将在配置更改时被销毁。它可能不起作用的另一个原因是,如果允许保留片段非保留片段都存在于同一个 backstack 上,事情可能会变得棘手。

在哪些用例中使用此方法有意义?

保留的片段对于跨活动实例传播状态信息(尤其是线程管理)非常有用。例如,片段可以作为Thread或的实例的主机AsyncTask,管理其操作。有关更多信息,请参阅我关于此主题的博客文章。

一般来说,我会将它onConfigurationChanged与使用Activity...类似地对待它,不要仅仅因为您太懒而无法正确实现/处理方向更改而将其用作创可贴。仅在需要时使用它。

于 2012-07-03T20:48:00.317 回答
28

setRetaininstance仅当您activity由于配置更改而被销毁和重新创建时才有用,因为实例是在调用onRetainNonConfigurationInstance. 也就是说,如果您旋转设备,保留的片段将保留在那里(它们不会被破坏和重新创建。)但是当运行时终止活动以回收资源时,什么都不会留下。当您按下后退按钮并退出活动时,一切都被破坏了。

通常我使用这个功能来保存方向更改时间。假设我从服务器下载了一堆位图,每个是 1MB,当用户不小心旋转他的设备时,我当然不想再做所有的下载工作。所以我创建了一个Fragment保存我的位图并将其添加到管理器并调用setRetainInstance,即使屏幕方向发生变化,所有位图仍然存在。

于 2014-09-06T05:27:17.647 回答
13

SetRetainInstance(true) 允许片段生存。其成员将在轮换等配置更改期间保留。但是当活动在后台被杀死时,它仍然可能被杀死。如果后台的包含活动被系统杀死,它的 instanceState 应该由您正确处理 onSaveInstanceState 的系统保存。换句话说,onSaveInstanceState 将始终被调用。虽然如果 SetRetainInstance 为 true 并且片段/活动尚未被杀死,则不会调用 onCreateView,但如果它被杀死并被尝试恢复,它仍然会被调用。

以下是对android活动/片段的一些分析,希望对您有所帮助。 http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html

于 2014-01-15T14:23:58.757 回答
9

setRetainInstance() - 已弃用

作为片段版本 1.3.0-alpha01

片段上的 setRetainInstance() 方法已被弃用。随着 ViewModel 的引入,开发人员可以使用特定的 API 来保留可以与活动、片段和导航图相关联的状态。这允许开发人员使用正常的、未保留的 Fragment 并将他们想要保留的特定状态分开,避免常见的泄漏源,同时保持保留状态的单个创建和销毁的有用属性(即 ViewModel 的构造函数以及它收到的 onCleared() 回调)。

于 2020-03-28T21:35:03.800 回答
2

setRetainInstance(boolean)当你想要一些不依赖于 Activity 生命周期的组件时很有用。例如,rxloader使用这种技术来“为 rxjava 的 Observable 处理 Android 的活动生命周期”(我在这里找到了)。

于 2015-09-03T08:44:51.747 回答