首页 文章

理解Fragment的setRetainInstance(boolean)

提问于
浏览
293

从文档开始:

public void setRetainInstance(boolean retain)控制是否在Activity重新创建(例如从配置更改)中保留片段实例 . 这只能用于不在后栈中的片段 . 如果设置,重新创建活动时片段生命周期将略有不同:onDestroy()将不会被调用(但是onDetach()仍将是,因为片段正在与其当前活动分离) . 因为片段没有被重新创建,所以不会调用onCreate(Bundle) . onAttach(Activity)和onActivityCreated(Bundle)仍将被调用 .

我有一些问题:

  • 片段是否也保留其视图,还是会在配置更改时重新创建?到底是什么“保留”?

  • 当用户离开活动时,片段是否会被销毁?

  • 为什么它不能与后栈上的片段一起使用?

  • 哪些是使用此方法有意义的用例?

4 回答

  • 311

    如果您想要一些与Activity生命周期无关的组件,setRetainInstance(boolean)非常有用 . 例如,rxloader到"handle Android's activity lifecyle for rxjava's Observable"(我发现here)使用了这种技术 .

  • 2

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

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

  • 25

    首先,查看保留碎片的my post . 它可能有所帮助 .

    现在回答你的问题:

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

    是的, Fragment 的状态将在整个配置更改中保留 . 具体来说,"retained"表示在配置更改时不会破坏该片段 . 也就是说,即使配置更改导致底层 Activity 被销毁, Fragment 也将被保留 .

    当用户离开活动时,片段是否会被销毁?

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

    为什么它不能与后端堆栈上的碎片一起使用?

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

    使用此方法有意义的用例是什么?

    保留的片段对于跨活动实例传播状态信息(尤其是线程管理)非常有用 . 例如,片段可以充当 ThreadAsyncTask 实例的主机,从而管理其操作 . 有关更多信息,请参阅本主题的my blog post .

    一般来说,我会把它视为使用 onConfigurationChangedActivity 类似...不要仅仅因为你太懒而无法正确实现/处理方向更改 . 只在需要时使用 .

  • 12

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

    通常我使用此功能来保存方向更改时间 . 我从服务器下载了一堆Bitmaps,每一个都是1MB,当用户意外旋转他的设备时,我当然不会我想再次完成所有的下载工作 . 所以我创建一个 Fragment 拿着我的位图并将其添加到管理器并调用 setRetainInstance ,即使屏幕方向改变,所有位图仍然存在 .

相关问题