从文档开始:
public void setRetainInstance (boolean retain)
Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack. If set, the fragment lifecycle will be slightly different when an activity is recreated:
onDestroy() will not be called (but onDetach() still will be, because the fragment is being detached from its current activity).
onCreate(Bundle) will not be called since the fragment is not being re-created.
onAttach(Activity) and onActivityCreated(Bundle) will still be called.
我有几个问题:
片段是否也保留它的视图,或者在配置更改时重新创建视图?“保留”到底是什么意思?
当用户离开活动时,片段会被销毁吗?
为什么它不能与后面堆栈上的片段一起工作?
在哪些用例中使用这种方法是有意义的?
首先,看看我关于留存碎片的帖子。这可能会有帮助。
现在来回答你们的问题:
片段是否也保留它的视图状态,或者在配置更改时重新创建视图状态——究竟“保留”的是什么?
是的,片段的状态将在配置更改期间被保留。具体来说,“保留”意味着片段不会在配置更改时被销毁。也就是说,即使配置更改导致底层活动被销毁,片段也将被保留。
当用户离开活动时,片段会被销毁吗?
Just like Activitys, Fragments may be destroyed by the system when memory resources are low. Whether you have your fragments retain their instance state across configuration changes will have no effect on whether or not the system will destroy the Fragments once you leave the Activity. If you leave the Activity (i.e. by pressing the home button), the Fragments may or may not be destroyed. If you leave the Activity by pressing the back button (thus, calling finish() and effectively destroying the Activity), all of the Activitys attached Fragments will also be destroyed.
为什么它不能与后面堆栈上的片段一起工作?
There are probably multiple reasons why it's not supported, but the most obvious reason to me is that the Activity holds a reference to the FragmentManager, and the FragmentManager manages the backstack. That is, no matter if you choose to retain your Fragments or not, the Activity (and thus the FragmentManager's backstack) will be destroyed on a configuration change. Another reason why it might not work is because things might get tricky if both retained fragments and non-retained fragments were allowed to exist on the same backstack.
在哪些用例中使用这种方法是有意义的?
保留片段对于跨活动实例传播状态信息(尤其是线程管理)非常有用。例如,一个片段可以作为一个线程或AsyncTask实例的宿主,管理它的操作。更多信息请参见我的博客文章。
一般来说,我会把它类似于使用onConfigurationChanged与一个活动…不要仅仅因为你懒得正确地实现/处理方向变化就把它当作一个创可贴。只在你需要的时候使用它。
setRetainInstance() -已弃用
As Fragments Version 1.3.0-alpha01
The setRetainInstance() method on Fragments has been deprecated. With
the introduction of ViewModels, developers have a specific API for
retaining state that can be associated with Activities, Fragments, and
Navigation graphs. This allows developers to use a normal, not
retained Fragment and keep the specific state they want retained
separate, avoiding a common source of leaks while maintaining the
useful properties of a single creation and destruction of the retained
state (namely, the constructor of the ViewModel and the onCleared()
callback it receives).
首先,看看我关于留存碎片的帖子。这可能会有帮助。
现在来回答你们的问题:
片段是否也保留它的视图状态,或者在配置更改时重新创建视图状态——究竟“保留”的是什么?
是的,片段的状态将在配置更改期间被保留。具体来说,“保留”意味着片段不会在配置更改时被销毁。也就是说,即使配置更改导致底层活动被销毁,片段也将被保留。
当用户离开活动时,片段会被销毁吗?
Just like Activitys, Fragments may be destroyed by the system when memory resources are low. Whether you have your fragments retain their instance state across configuration changes will have no effect on whether or not the system will destroy the Fragments once you leave the Activity. If you leave the Activity (i.e. by pressing the home button), the Fragments may or may not be destroyed. If you leave the Activity by pressing the back button (thus, calling finish() and effectively destroying the Activity), all of the Activitys attached Fragments will also be destroyed.
为什么它不能与后面堆栈上的片段一起工作?
There are probably multiple reasons why it's not supported, but the most obvious reason to me is that the Activity holds a reference to the FragmentManager, and the FragmentManager manages the backstack. That is, no matter if you choose to retain your Fragments or not, the Activity (and thus the FragmentManager's backstack) will be destroyed on a configuration change. Another reason why it might not work is because things might get tricky if both retained fragments and non-retained fragments were allowed to exist on the same backstack.
在哪些用例中使用这种方法是有意义的?
保留片段对于跨活动实例传播状态信息(尤其是线程管理)非常有用。例如,一个片段可以作为一个线程或AsyncTask实例的宿主,管理它的操作。更多信息请参见我的博客文章。
一般来说,我会把它类似于使用onConfigurationChanged与一个活动…不要仅仅因为你懒得正确地实现/处理方向变化就把它当作一个创可贴。只在你需要的时候使用它。