Fragment 生命周期解惑
以下都是基于
androidx.fragment:fragment:1.2.4
分析
正常加载
onAttach
-> onCreate
-> onCreateView
-> onActivityCreated
-> onStart
-> onResume
正常退出
onPause
-> onStop
-> onDestroyView
-> onDestroyView
-> onDestroy
-> onDetach
。
注意到加载时有
onActivityCreated
但是退出时却没有onActivityDestroyed
。这个生命周期为什么表现出不对称性?原因是这个 1.2.4 版本的Fragment
还处于改进中,在之后的 1.3.0 版本中,onActivityCreated
将被标记为 Deprecated。和View
相关的代码应写在onCreateView
中,其他的初始化代码应写在onCreate
中。如果确实关心Activity
的生命周期,应该在onAttach
中注册LifecyclerObserver
来观察Activity
的生命周期。release note: fragment#1.3.0-alpha02class MyFragment : Fragment(), LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreated(){ activity?.lifecycle?.removeObserver(this) } override fun onAttach(context: Context) { super.onAttach(context) activity?.lifecycle?.addObserver(this) } }
旋转屏幕时
onPuase
-> onStop
-> onSavedInstanceState
-> onDestroyView
-> onDestroy
-> onDetach
-> 正常加载流程
如果
Activity
没有配置android:configChanges
,那么屏幕旋转时,Activity
和Fragment
都会经过销毁和重建的过程。在销毁时,由于可能被重建,因此会调用onSavedInstanceState
来保存状态(退出时就不会调用,因为退出时不需要保存状态)。之所以旋转屏幕要销毁和重建,主要是为了让开发者有机会在横屏时重新加载横屏时的布局(通过布局的 land 维度)。
如果配置了android:configChanges='orientation|screenSize'
,那么就表示开发者自己处理横屏的情况,不需要销毁、重建Activity
、Fragment
。此时系统会回调Activity.onConfigurationChanged()
和Fragment.onConfigurationChanged()
,传递Configuration
对象,开发者根据该对象中新的设备配置信息,自己决定对资源进行适当修改。上面的
onSavedInstanceState
主要用于保存销毁时必要的信息,这样可以在重建后的Fragment
中拿回这些信息。如果使用ViewModel
的话,由于它自身能够跨越 销毁 - 重建 的生命周期,因此可以不用使用onSavedInstanceState
方法。
退回 HOME 页面,再回来
onPause
-> onStop
-> onSaveInstanceState
。
- 如果
Fragment
没有被销毁,那么再回到Fragment
时,走onStart
->onResume
流程。 - 如果
Fragment
被销毁了,那么再回到Fragment
时,正常的创建Fragment
过程,开发者有机会在onCreate
、onCreateView
和onActivityCreate
时恢复数据
Fragment
跟Activity
一样有onSaveInstanceState
回调来保存临时数据,但是却没有onRestoreInstanceState
来恢复临时数据。Fragment
的数据恢复是在onCreate(Bundle)
、onCreateView(LayoutInflater, ViewGroup, Bundle)
和onActivityCreated(Bundle)
(该回调之后会被移除) 中进行恢复的,用于提供给开发者不同的恢复时机。