理解片段的setRetainInstance(boolean)
从文档开始:
public void setRetainInstance(boolean retain)
控制是否在重新创buildActivity(例如从configuration更改)中保留片段实例。 这只能用于不在后面堆栈中的碎片。 如果设置,则在重新创build活动时,片段生命周期将略有不同:
- onDestroy()将不会被调用(但onDetach()仍然会,因为片段正在从它当前的活动分离)。
- onCreate(Bundle)将不会被调用,因为片段不被重新创build。
- onAttach(Activity)和onActivityCreated(Bundle)仍然会被调用。
我有一些疑问:
-
片段是否也保留其视图,或者在configuration更改时重新创build? 什么是“保留”?
-
当用户离开活动时,碎片会被破坏吗?
-
为什么它不能在后面的堆栈中使用碎片?
-
哪些是使用这种方法有意义的用例?
首先,看看我保留的碎片上的post 。 这可能有帮助。
现在回答你的问题:
片段是否还保留其
视图状态,还是会在configuration更改时重新创build – 究竟是“保留”的?
是的, Fragment
的状态将在configuration更改中保留。 具体而言,“保留”意味着碎片不会在configuration更改时被破坏。 也就是说,即使configuration更改导致基础Activity
被破坏, Fragment
也将被保留 。
当用户离开活动时,碎片会被破坏吗?
就像Activity
一样,当内存资源不足时,系统可能会破坏Fragment
。 无论您的碎片是否保留其configuration更改的实例状态,都不会影响系统是否会在离开Activity
摧毁Fragment
。 如果您离开Activity
(即通过按主页button), Fragment
可能会或可能不会被破坏。 如果通过按下后退button离开Activity
(因此,调用finish()
并有效地销毁Activity
),所有Activity
的附加Fragment
也将被销毁。
为什么它不能在后面的堆栈中使用碎片?
可能有多种原因不支持,但最明显的原因是Activity
对FragmentManager
有引用,而FragmentManager
对后台进行pipe理。 也就是说,不pipe你select保留你的Fragment
还是不保留, Activity
(也就是FragmentManager
的backstack)将会在configuration改变时被破坏。 另一个原因可能不起作用的原因是,如果保留的片段和非保留的片段被允许存在于同一个后台堆栈中,事情可能会变得棘手。
哪些是使用这种方法有意义的用例?
保留的片段对于跨活动实例传播状态信息(尤其是线程pipe理)非常有用。 例如,一个片段可以作为一个Thread
或AsyncTask
实例的主机,来pipe理它的操作。 有关更多信息,请参阅关于此主题的博客文章 。
一般来说,我会像使用onConfigurationChanged
一样使用Activity
…不要将它用作onConfigurationChanged
,因为您太懒惰,无法正确实现/处理方向更改。 只有在需要时才使用它。
setRetaininstance
仅在您的activity
由于configuration更改而被销毁和重新创build时有用,因为在调用onRetainNonConfigurationInstance
期间保存实例。 也就是说,如果旋转设备,保留的碎片将保留在那里(它们不会被销毁并重新创build),但是当运行时间杀死活动来回收资源时,什么也不留下。 当你按下退出button并退出活动时,一切都被破坏。
通常我使用这个function来保存方向改变的时间。我从服务器上下载了一堆Bitmaps,每个都是1MB,当用户不小心旋转他的设备时,我当然不想再做所有的下载工作。我创build了一个持有我的位图的Fragment
,并将其添加到pipe理器并调用setRetainInstance
,即使屏幕方向更改,所有Bitmap仍然存在。
SetRetainInstance(true)允许片段sorting生存。 其成员将在configuration更改期间保留,如旋转。 但是当这个活动在后台被杀的时候,它仍然可能会被杀死。 如果后台包含的活动被系统杀死,那么它的实例状态应该由你在onSaveInstanceState中正确处理的系统保存。 换句话说,onSaveInstanceState将始终被调用。 尽pipe如果SetRetainInstance为true并且fragment / activity还没有被杀死的话,onCreateView将不会被调用,但是如果它被终止并被尝试返回,仍然会被调用。
这里有一些android的活动/片段的分析,希望它有帮助。 http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html
setRetainInstance(boolean)当你想要有一些没有绑定到Activity生命周期的组件时很有用。 这个技术被rxloader用来“处理rxjava的Observable的Android活动生命周期”(我在这里已经find了 )。