理解片段的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也将被销毁。

为什么它不能在后面的堆栈中使用碎片?

可能有多种原因不支持,但最明显的原因是ActivityFragmentManager有引用,而FragmentManager对后台进行pipe理。 也就是说,不pipe你select保留你的Fragment还是不保留, Activity (也就是FragmentManager的backstack)将会在configuration改变时被破坏。 另一个原因可能不起作用的原因是,如果保留的片段非保留的片段被允许存在于同一个后台堆栈中,事情可能会变得棘手。

哪些是使用这种方法有意义的用例?

保留的片段对于跨活动实例传播状态信息(尤其是线程pipe理)非常有用。 例如,一个片段可以作为一个ThreadAsyncTask实例的主机,来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了 )。