为什么要使用Fragment#setRetainInstance(boolean)?


68

我发现Fragment#setRetainInstance(true)令人困惑。这是从Android Developer API中提取的Javadoc :

public void setRetainInstance(布尔值保留)

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

  • onDestroy()将不会被调用(但onDetach()仍会被调用,因为该片段正在从其当前活动中分离出来)。
  • 由于不会重新创建片段,因此不会调用onCreate(Bundle)。
  • onAttach(活动)和onActivityCreated(捆绑)仍然被调用。

问题:作为开发人员,您如何使用它?为什么它使事情变得更容易?



1
onDestroy()如果设备的内存不足,将被调用
James Goodwin

Answers:


90

您作为开发人员如何使用此功能

致电setRetainInstance(true)。我通常在onCreateView()onActivityCreated()中使用它。

为什么它使事情变得更容易?

它往往比onRetainNonConfigurationInstance()处理跨配置更改的数据保留(例如,将设备从纵向旋转到横向)更简单。非保留的片段将在配置更改时被销毁并重新创建;保留的片段不是。因此,那些保留的片段保存的任何数据都可用于配置后更改活动。


@CommonsWare-如果您在一个Activity中创建一个新片段,并且该Activity被重新创建,如何避免再次创建一个新片段?
尼尔

4
@Neil:查看片段是否存在(例如findFragmentById())。如果存在,请不要重新创建。
CommonsWare,2012年

1
@androiddeveloper:“如果该片段保留其视图,以便不必重新创建它们(在onCreate()方法中),则可能会占用一些内存” –欢迎尝试重新创建小部件的父级参加这项新活动,但我的运气是零。AFAIK,您需要在中重新创建小部件onCreateView()。“但是,我认为可以使用softReference / weakReference代替此任务,对吗?” -什么任务?
CommonsWare

3
@ e.shishkin:应该的。我很少onCreate()在一个片段中实现,因此我没有尝试过。
CommonsWare

1
@ e.shishkin您可以随时调用它。从技术上讲,您甚至不需要在生命周期方法中调用它(尽管通常这不是您想要/不需要做的事情)。
Alex Lockwood

48

这对于保持长期运行的资源(例如套接字)非常有用。有一个没有UI的片段,其中包含对蓝牙套接字的引用,当用户翻转手机时,您不必担心重新连接它们。

在保留对加载时间很长的资源(如位图或服务器数据)的引用时也很方便。加载一次,将其保留在保留的片段中,当重新加载活动时,它仍然存在,而您不必重新构建它。


真好 但是,如果我们需要刷新它们怎么办?
Anshul Tyagi

32

很晚才添加了此答案,但我认为这样可以使事情更清晰。跟我说。什么时候setRetainInstance是:

  • 片段在配置更改时重新创建。NEW INSTANCE已创建。
  • 所有生命周期方法都会在配置更改时调用,包括onCreate()onDestroy()

真正

  • 片段不会在配置更改时重新创建。使用相同的实例。
  • 在配置更改,APART FROMonCreate()和上调用所有生命周期方法onDestroy()
  • 将实例添加到Backstack后,保留实例将不起作用。

不要忘记,以上内容适用于DialogFragment以及Fragments。


1
您可以添加参考Retaining an instance will not work when added to the backstack. ?
nmxprime


1
万一将片段添加到后台,如何恢复片段的状态?savedInstanceState为null,我不能使用setRetainInstance ...
android开发人员

1

setRetainInstance(boolean)方法已过时,请改用ViewModels。

从片段API版本1.3.0setRetainInstance(boolean)开始不赞成使用片段方法。

随着ViewModels的引入,开发人员拥有一个特定的API,用于保留可以与Activity,Fragments和Navigation图相关联的状态。这使开发人员可以使用正常的,未保留的Fragment并将他们想要保留的特定状态分开。

这样可确保开发人员为这些Fragment(与它们的所有其余Fragments匹配)提供了更易理解的生命周期,同时保持了单个创建和单个销毁的有用属性(在本例中,是的构造函数ViewModel和的onCleared()回调)的ViewModel)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.