系列
Fragment (一):Fragment使用详解
Fragment (二):Activity 和Fragment 的异常销毁、状态保存和恢复机制
Fragment (三):源码解析Fragment 返回栈原理
异常销毁
不了解Fragment 使用、生命周期、常用API等的可用先简单看下:Fragment使用详解
- 概念:异常销毁,即不是由于用户主动退出Activity导致其被销毁(比如按BACK键后Activity被主动销毁),而是由于其他非正常情况导致的销毁。
注:Activity的异常销毁会导致Fragment的异常销毁。
可能导致Activity的异常销毁的几种情况:
- 按HOME键返回桌面时
- 按菜单键回到系统后台,并选择了其他应用时
- 按电源键时
- 屏幕方向切换时
Android系统中,当可能导致Activity的异常销毁时,会触发Activity和它的所有active fragment 的onSaveInstanceState()保存开发者需要保存的Activity /Fragment状态,同时还会自动保存它们各自的View 状态。若Activity被异常销毁,再次回到该Activity时会重建该Activity和它被销毁前的所有active fragment,并恢复被保存的状态。
**注:**fragment 的hide 和show 不会被保存,所有重建的fragment 的状态都是show,除非在fragment的oncreate()中设置setRetianInstance(true),因为该fragment不会随宿主Activity的销毁而销毁,但该fragment 不能加入返回栈,具体参考:Fragment使用详解中没有视图的Fragment的用处。
“前台”fragment:调用了add()但既没有被销毁也尚未被移到返回栈中的fragment 。
FragmentManagerImpl 中有两个重要的Field:
- mAdded:fragment列表,保存所有前台fragment 。
- mActive:fragment列表,保存所有前台fragment 和返回栈中的fragment ,实际上就是active fragment。
状态类型
状态分两种:
- Activity /Fragment状态:开发者手动保存Activity /Fragment 持有的变量。
- View状态:系统自动保存设置了id的View的状态(TextView还需要设置android:freezeText=”true”)。
Activity /Fragment 状态
触发Activity /Fragment 状态保存和恢复只有一种情形:异常销毁。
Activity /Fragment 状态的保存
当可能发生异常销毁时会自动调用Activity和所有active fragment 的onSaveInstanceState()。开发者可重写Activity /Fragment 的onSaveInstanceState(),保存Activity /Fragment状态到savedInstanceState() 中(注:不要忘了调用父类方法)。Activity的onSaveInstanceState()在onStop()之后,onDestroy()之前或之后触发。
Activity 状态的恢复
可以在onCreate(Bundle savedInstanceState)、onRestoreInstanceState(Bundle savedInstanceState)这两个方法中的savedInstanceState 获取保存的Activity 状态。- Fragment 状态的恢复
可以在onCreate(Bundle savedInstanceState)、onActivityCreated(Bundle savedInstanceState)这两个方法中的savedInstanceState 获取保存的Fragment 状态。
Activity /Fragment 状态保存适用于保存占用存储空间较小的数据,若有数据占用存储空间较大,比如图片,则需要使用没有UI 的Fragment来保存,具体参考:fragment 状态保存和恢复。
View状态
实现View状态的自动保存,需要为每个View 设置id。TextView 还需要设置android:freezeText=”true”。
触发Activity 的View 状态保存和恢复只有一种情形:异常销毁。
触发Fragment 的View 状态保存和恢复的两种情形:
1、异常销毁。
2、事务进出返回栈。
View状态的保存
无论是对Activity还是Fragment中View状态的保存,本质上都是通过调用Activity /Fragment 中顶级View的saveHierarchyState() 从而实现对Activity /Fragment 中View tree的深度遍历并调用每个View 的onSaveInstanceState() 保存View状态。
除了Fragment 的View状态是保存在Fragment 的一个Field 中外,Activity /Fragment 状态和View状态最终都保存在Activity的一个Field 中。(具体看后面源码分析)1、异常销毁:Activity的onSav