理解片段的setRetainInstance(boolean)

时间:2012-06-25 00:07:02

标签: android android-fragments

从文档开始:

  

public void setRetainInstance(boolean retain)

     

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

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

我有一些问题:

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

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

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

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

5 个答案:

答案 0 :(得分:319)

首先,查看保留片段的my post。这可能有所帮助。

现在回答你的问题:

  

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

是的,Fragment的状态将在整个配置更改中保留。具体来说,“保留”表示在配置更改时将破坏该片段。也就是说,Fragment保留,即使配置更改导致基础Activity被销毁。

  

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

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

  

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

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

  

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

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

一般情况下,我会将onConfigurationChangedActivity类似地对待它...不要仅仅因为你太懒而无法正确实现/处理方向更改。只在需要时才使用它。

答案 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)

setRetainInstance()-已弃用

作为碎片Version 1.3.0-alpha01

不建议使用Fragments上的setRetainInstance()方法。用 在引入ViewModels之后,开发人员可以使用特定的API 保留可以与“活动”,“片段”和“ 导航图。这使开发人员可以使用普通的,而不是 保留Fragment并保留要保留的特定状态 分开,避免常见的泄漏源,同时保持 单个创建和销毁保留项的有用属性 状态(即ViewModel和onCleared()的构造函数 收到的回调)。

答案 4 :(得分:2)

当您想拥有一些与Activity生命周期无关的组件时,

setRetainInstance(boolean)非常有用。这种技术例如由rxloader用于“处理Android的rxjava Observable的活动生命周期”(我发现here)。