主要方法
- onSaveInstanceState(Bundle outState)
- onRestoreInstanceState(Bundle savedInstanceState)
调用时机
onSaveInstanceState(Bundle outState)
从Android P开始,该方法如果被调用,也是在onStop之后;
在Android P之前,则会在onStop之前调用,但是不能保证是在onPause之前还是之后;
onRestoreInstanceState(Bundle savedInstanceState)
onStart()之后,onPostCreate() 之前执行,并且只有在重新创建Activity的时候才会执行
不过一般的实现是在onCreate()中拿到保存的bundle进行自定义的恢复逻辑;
在onRestoreInstanceState()中会默认恢复View层级的状态信息.
onSaveInstanceState()
在onStop之后都会执行(AndroidP前后版本可能会有所差异),但是onRestoreInstanceState()
则只在某些特定的场景才会执行:
在“开发者选项-不保留活动”中设置,从Activity A跳转到Activity B再返回,也会执行
onRestoreInstanceState()
这种情况下,Activity重建时可能会onResume()-onPause()-onResume();
App处于后台,被系统回收,导致Activity被销毁,当再次重启Activity的时候;
配置信息变更的时候,比如屏幕方向切换的时候;
在onCreate()中的savedInstanceState有可能为null,而onRestoreInstanceState()中的savedInstanceState()则一定不为null;
保存了什么状态
各种状态都是保存到Bundle中的,如果有比较复杂的结构,就使用Parcelable.
主要存储了以下信息:
View层级中View的状态信息
- 具有ID的View的信息
- 拥有焦点的View的信息
- 状态信息存储在不同View中的BaseSavedState中,这个类是一个Parcelable类
Fragment信息
Dialog信息
不同的View中可以有不同的BaseSavedState实现,用来保存各自的信息,比如在ViewPager2中保存的信息时当前选中的位置.
而且View中也有对应的onSaveInstanceState()方法,用于保存自身的状态信息.
保存在哪了
保存到了磁盘(及手机上的存储器)上(这一点存疑)
持久化的问题
有一个PersistableBundle
可以当作持久化的状态保存.
在onCreate(),onsaveInstanceState(),onRestoreInstanceState()中也有对应的参数传递.
但是目前在应用层很少使用这个类.
源码分析
state bundle的创建
在ActivityThread中有:
private void callActivityOnSaveInstanceState(ActivityClientRecord r) {
r.state = new Bundle();
r.state.setAllowFds(false);
if (r.isPersistable()) {
r.persistentState = new PersistableBundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
}
保存了什么状态
在Activity中有:
final void performSaveInstanceState(@NonNull Bundle outState) {
dispatchActivityPreSaveInstanceState(outState);
// View层级信息
onSaveInstanceState(outState);
// Dialog信息
saveManagedDialogs(outState);
// Fragment信息
mActivityTransitionState.saveState(outState);
// 是否请求过权限
storeHasCurrentPermissionRequest(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
dispatchActivityPostSaveInstanceState(outState);
}
protected void onSaveInstanceState(@NonNull Bundle outState) {
// View层级信息,mWindow最终也是通过DecorView去获取的层级信息
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
// 自动填充的内容
outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mAutoFillResetNeeded) {
outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
getAutofillManager().onSaveInstanceState(outState);
}
dispatchActivitySaveInstanceState(outState);
}