Activity状态的保存和恢复
Activity被killed或者配置发生变化前会调用onSaveInstanceState (Bundle)来保存Activity状态以便在onCreate(Bundle)或onRestoreInstanceState(Bundle)中恢复。正常的生命周期中onSaveInstanceState (Bundle)和onRestoreInstanceState(Bundle)是不会被调用。
onSaveInstanceState (Bundle)是在onStop()前调用,但是无法保证和onPause()的调用顺序。onRestoreInstanceState(Bundle)的调用发生在onStart()和onPostCreate(Bundle)中间。
onSaveInstanceState (Bundle)的默认实现是通过调用Activity布局中的每个设置了android:id属性的View的onSaveInstanceState (Bundle)来保存每个View的状态。然后在onRestoreInstanceState(Bundle)中根据对应的id恢复View的状态。
所以,View状态要能够保存和恢复,需要满足两点:
- 在
onSaveInstanceState (Bundle)和onRestoreInstanceState(Bundle)中保存和恢复状态。 - 设置了
android:id以便根据id恢复View状态。
TextView不仅需要设置android:id还需要设置android:freezesText="true"才能保存状态。查看TextView的onSaveInstanceState (Bundle)方法,当变量mFreezesText为true时才会保存TextView的状态。
Activity状态的保存和恢复过程如下:
所以,对于Activity的成员变量需要我们自己手动保存和恢复。
private int countCanRestored = 0;
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("countCanRestored", countCanRestored);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
countCanRestored = savedInstanceState.getInt("countCanRestored", 0);
...
}
复制代码
Fragment状态的保存和恢复
当系统资源不足导致Fragment被销毁或者配置发生变化时,Fragment状态的保持和恢复跟Activity类似。
Activity状态的保存和恢复过程如下:
onSaveInstanceState(Bundle)方法却没有
onRestoreInstanceState(Bundle)方法。对应地,Fragment是在
onCreate(Bundle),
onCreateView(LayoutInflater, ViewGroup, Bundle),
onActivityCreated(Bundle)方法中恢复View状态和成员变量。需要注意的是Bundle可能为空,使用前需要判断一下。
下面考虑两种比较特殊的情况:
setRetainInstance(true);当配置发生变化时,Fragment不会随着Activity的消毁而消毁,Fragment的实例还是存在的,只是onDestroyView()方法被调用,View被销毁了。Fragment的成员变量和View状态都会被系统自动保存和恢复。onSaveInstanceState(Bundle)和onActivityCreated(Bundle)和onCreateView(LayoutInflater, ViewGroup, Bundle)方法会被调用。onCreate(Bundle)不会被调用。- Fragment从Activity的
back stack中恢复。Fragment的实例并没有被销毁,只是onDestroyView方法被调用,View被销毁了。Fragment的成员变量和View状态都会被系统自动保存和恢复。onSaveInstanceState和onCreate(Bundle)没有被调用。onActivityCreated(Bundle)和onCreateView(LayoutInflater, ViewGroup, Bundle)方法会被调用。
所以保持和恢复Activity和Fragment状态的正确姿势是:
- 确保需要保存和恢复状态的View重写了
onSaveInstanceState (Bundle)和onRestoreInstanceState(Bundle)这个两个方法。有的View还需要手动开启这项功能,比如TextView需要设置android:freezesText="true"。当我们使用第三方自定义View时需要确保是否已经实现了这两个方法。如果没有,可以继承这个View,重写这个两个方法。我们自己自定义View的时候也要记得实现这两个方法。 - 给需要保存和恢复状态的View设置
android:id。 - 保存和恢复Activity和Fragment的实例变量。
Reference:inthecheesefactory.com/blog/fragme…
348

被折叠的 条评论
为什么被折叠?



