理解fragment的setRetainInstance(boolean)

从文档开始:

setRetainInstance (boolean retain)

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

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

我有几个问题:

  • 片段是否也保留它的视图,或者在配置更改时重新创建视图?“保留”到底是什么?的意思吗?

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

  • 为什么它不能与后面堆栈上的片段一起工作?

  • 在哪些用例中使用这个方法是有意义的?

179716 次浏览

首先,检查保留片段上的< >强劲我的帖子< / >强。这可能会有帮助。

现在来回答你们的问题:

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

是的,Fragment的状态将在配置更改期间保留。具体来说,"retain "意味着该片段将在配置更改时被销毁。也就是说,即使配置更改导致底层的Activity被销毁,Fragment也将是保留

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

就像__abc0一样,当内存资源不足时,__abc1可能会被系统销毁。当你离开Activity时,你是否让你的片段在配置更改时保留它们的实例状态对系统是否会销毁__abc1没有影响。如果你离开Activity(即通过按home键),__abc1可能会被销毁,也可能不会被销毁。如果你通过按返回按钮离开Activity(因此,调用finish()并有效地销毁Activity),所有附带__abc1的Activity也将被销毁。

为什么它不能与后面堆栈上的片段一起工作?

不支持它可能有多种原因,但对我来说最明显的原因是Activity保存了对FragmentManager的引用,而FragmentManager管理背堆栈。也就是说,无论你是否选择保留你的__abc3, Activity(因此FragmentManager的后台堆栈)将在配置更改时被销毁。另一个原因是,如果两个保留片段而且非保留片段被允许存在于同一个回堆栈上,事情可能会变得棘手。

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

保留片段对于跨活动实例传播状态信息(尤其是线程管理)非常有用。例如,一个片段可以作为ThreadAsyncTask实例的宿主,管理它的操作。有关此主题的更多信息,请参阅我的博客文章

一般来说,我将类似于使用onConfigurationChangedActivity…不要仅仅因为你懒得正确地实现/处理方向变化就把它当作一个创可贴。只在你需要的时候使用它。

SetRetainInstance(true)允许片段存活。它的成员将在配置更改(如旋转)期间保留。但当活动在后台被终止时,它仍然可能被终止。如果在后台包含的活动被系统杀死,它的instanceState应该被你正确处理onSaveInstanceState的系统保存。换句话说,onSaveInstanceState总是会被调用。虽然onCreateView不会被调用,如果SetRetainInstance为真,片段/活动还没有被杀死,它仍然会被调用,如果它被杀死,并试图被带回来。

下面是一些关于android activity/fragment的分析,希望对大家有所帮助。 http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html < / p >

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

通常我用这个函数来保存方向改变时间。假设我从服务器上下载了一堆位图,每个位图都是1MB,当用户不小心旋转了他的设备时,我当然不想再做所有的下载工作。因此,我创建了一个Fragment保存我的位图,并将其添加到管理器并调用setRetainInstance,即使屏幕方向发生变化,所有的位图仍然存在。

当你想要某个组件不绑定到Activity生命周期时,setRetainInstance(布尔)是有用的。例如,rxloader用于“为rxjava的Observable处理Android的活动生命周期”(我已经找到了在这里)。

setRetainInstance() -已弃用

As Fragments 版本1.3.0-alpha01

片段上的setRetainInstance()方法已弃用。与 ViewModels的引入,开发人员有一个特定的API 可以与活动、片段和相关联的保留状态 导航图。这允许开发人员使用正常的,而不是 保留片段并保留他们想要保留的特定状态 分开,避免了一个共同的泄漏源,同时维护 单个有用属性的创建和销毁保留 状态(即ViewModel和onCleared()的构造函数)