从文档开始:
public void setRetainInstance(boolean retain)
控制是否在活动重新创建(例如从配置更改)中保留片段实例。这只能用于不在后栈中的片段。如果设置,则重新创建活动时片段生命周期将略有不同:
- onDestroy()将不会被调用(但onDetach()仍然会被调用,因为片段正在与其当前活动分离。)
- onCreate(Bundle)将不会被调用,因为片段没有被重新创建。
仍然会调用- onAttach(Activity)和onActivityCreated(Bundle)。
我有一些问题:
片段是否也保留其视图,还是会在配置更改时重新创建? “保留”究竟是什么意思?
当用户离开活动时,片段是否会被销毁?
为什么它不适用于后堆栈上的碎片?
哪些使用此方法有意义的用例?
答案 0 :(得分:319)
首先,查看保留片段的my post。这可能有所帮助。
现在回答你的问题:
片段是否也保留其
view状态,或者是否会在配置更改时重新创建 - 究竟是什么“保留”?
是的,Fragment
的状态将在整个配置更改中保留。具体来说,“保留”表示在配置更改时不将破坏该片段。也就是说,Fragment
将保留,即使配置更改导致基础Activity
被销毁。
当用户离开活动时,片段是否会被销毁?
就像Activity
s一样,当内存资源不足时,系统可能会销毁Fragment
。在您离开Fragment
后,是否让您的片段在配置更改中保留其实例状态不会影响系统是否会销毁Activity
。如果您离开Activity
(即按下主页按钮),Fragment
可能会被销毁,也可能不会被销毁。如果您通过按后退按钮离开Activity
(因此,调用finish()
并有效销毁Activity
),所有Activity
附加Fragment
s也将被摧毁。
为什么它不适用于后堆栈上的碎片?
可能有多种原因导致它不受支持,但最明显的原因是Activity
拥有FragmentManager
的引用,FragmentManager
管理后台堆栈。也就是说,无论您是否选择保留Fragment
,Activity
(以及FragmentManager
的后台堆叠)都将在配置更改时销毁。它可能不起作用的另一个原因是,如果允许保留的片段和非保留片段在同一个后台堆栈上存在,事情可能会变得棘手。
使用此方法有意义的用例是什么?
保留的片段对于跨活动实例传播状态信息(尤其是线程管理)非常有用。例如,片段可以充当Thread
或AsyncTask
实例的主机,从而管理其操作。有关详细信息,请参阅此主题的my blog post。
一般情况下,我会将onConfigurationChanged
与Activity
类似地对待它...不要仅仅因为你太懒而无法正确实现/处理方向更改。只在需要时才使用它。
答案 1 :(得分:25)
setRetaininstance
仅在由于配置更改而销毁并重新创建activity
时才有用,因为在调用onRetainNonConfigurationInstance
期间保存了实例。也就是说,如果您旋转设备,保留的片段将保留在那里(它们不会被销毁并重新创建。)但是当运行时杀死活动以回收资源时,不会留下任何内容。当您按下后退按钮并退出活动时,一切都将被销毁。
通常我使用此功能来保存方向更改Time.Say我从服务器下载了一堆Bitmaps,每一个都是1MB,当用户不小心旋转他的设备时,我当然不想做所有的下载工作所以,我创建一个Fragment
拿着我的位图并将其添加到管理器并调用setRetainInstance
,即使屏幕方向发生变化,所有位图仍然存在。
答案 2 :(得分:12)
SetRetainInstance(true)允许片段生存。其成员将在配置更改期间保留,如轮换。但是当活动在后台被杀死时它仍然可能被杀死。如果后台中的包含活动被系统杀死,那么它的instanceState应该由您在onSaveInstanceState上正确处理的系统保存。换句话说,将始终调用onSaveInstanceState。虽然如果SetRetainInstance为true且片段/活动尚未被杀死,则不会调用onCreateView,但如果它被杀死并被试图被带回,它仍会被调用。
以下是对android活动/片段的一些分析希望它有所帮助。 http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html
答案 3 :(得分:7)
不建议使用Fragments上的setRetainInstance()方法。用 在引入ViewModels之后,开发人员可以使用特定的API 保留可以与“活动”,“片段”和“ 导航图。这使开发人员可以使用普通的,而不是 保留Fragment并保留要保留的特定状态 分开,避免常见的泄漏源,同时保持 单个创建和销毁保留项的有用属性 状态(即ViewModel和onCleared()的构造函数 收到的回调)。
答案 4 :(得分:2)
setRetainInstance(boolean)非常有用。这种技术例如由rxloader用于“处理Android的rxjava Observable的活动生命周期”(我发现here)。