本文基于 Android 8.0 代码分析
Activity 生命周期中,我们知道 onSaveInstanceState 方法在 onPause 方法之后执行在onStop方法之前执行。这里我们首先看一下onPause方法的源码逻辑。熟悉 Activity 启动过程就知道生命周期处理主要在 ActivityThread 中完成。
ActivityThread.java
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState, String reason) {
...
// 1.
if (!r.activity.mFinished && saveState) {
// 2.
callCallActivityOnSaveInstanceState(r);
}
// 该方法中会回调到 Activity 的 onPause 方法
performPauseActivityIfNeeded(r, reason);
...
}
注释 1 处 r.activity.mFinished 为 false; saveState 查找传入参数位置知是 isPreHoneycomb的结果,小于 Android3.0 返回 true。
注释 2 处的方法就是调用 Activity 保存状态的方法 onSaveInstanceState 方法 ,且该方法执行先于 onPause 方法,关于该方法具体在后续分析。
从这里知道 在Android3.0 之前 onSaveInstanceState 回调是在 onPause 方法之前的。
继续 onStop 方法的调用过程
ActivityThread.java
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) {
// 1. 获取 ActivityClientRecord
ActivityClientRecord r = mActivities.get(token);
...
performStopActivityInner(r, info, show, true, "handleStopActivity");
}
private void performStopActivityInner(ActivityClientRecord r,
StopInfo info, boolean keepShown, boolean saveState, String reason) {
if (r != null) {
...
// 2.
if (!r.activity.mFinished && saveState) {
if (r.state == null) {
// 3. 执行 Activity 的 onSaveInstanceState 方法
callCallActivityOnSaveInstanceState(r);
}
}
if (!keepShown) {
try {
// 执行 Activity 的 onStop 方法
r.activity.performStop(false /*preserveWindow*/);
} ...
}
}
}
注释 1 处,mActivities 是 ArrayMap 集合,保存了 ActivityClientRecord,之后使用时只需 从 mActivities 中获取即可。
注释 2 处,r.activity.mFinished 依然为 false,saveState 查找传入参数发现直接传入的是 true,故该条件语句可以进入。
注释 3 处,该方法和前面提到的方法相同。
由此可知 在Android3.0 及以后 onSaveInstanceState 回调是在 onStop 方法之前的。
这里来看下 callCallActivityOnSaveInstanceState 做了什么事。
private void callCallActivityOnSaveInstanceState(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);
}
}
// Instrumentation.java
public void callActivityOnSaveInstanceState(Activity activity, Bundle outState) {
activity.performSaveInstanceState(outState);
}
// Activity.java
final void performSaveInstanceState(Bundle outState) {
// 1. 用于保存 Activity 状态
onSaveInstanceState(outState);
// 2. 会回调 管理的 Dialog 的 onSaveInstanceState 方法
saveManagedDialogs(outState);
mActivityTransitionState.saveState(outState);
storeHasCurrentPermissionRequest(outState);
}
数据的保存还是通过 ActivityClientRecord 的 state 来保存数据,其是 Bundle 类型。下面看看 Activity 的 onSaveInstanceState 做了哪些事情。
protected void onSaveInstanceState(Bundle outState) {
// 1. mWindow 就是 PhoneWindow
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
// 2. mFragment 是 FragmentController,其内部还是操作 HostCallbacks 对象,HostCallbacks 在 Activity 中创建,且是Activity 内部类
Parcelable p = mFragments.saveAllState();
...
}
该方法主要做了两件事:
下面看下 View 和 Fragment 的状态分别是怎么保存的。
mWindow 就是 PhoneWindow
PhoneWindow.java
@Override
public Bundle saveHierarchyState() {
Bundle outState = new Bundle();
if (mContentParent == null) {
return outState;
}
SparseArray<Parcelable> states = new SparseArray<Parcelable>();
// 1. View 层级各个View的状态保存
// mContentParent 就是 id 为 com.android.internal.R.id.content 的 View, 也就是 View 树中内容区域的根s布局
mContentParent.saveHierarchyState(states);
outState.putSparseParcelableArray(VIEWS_TAG, states);
// 2. 保存已获取焦点View 的id
final View focusedView = mContentParent.findFocus();
if (focusedView != null && focusedView.getId() != View.NO_ID) {
outState.putInt(FOCUSED_ID_TAG, focusedView.getId());
}
// 3. 保存 Panel 状态
SparseArray<Parcelable> panelStates = new SparseArray<Parcelable>();
savePanelState(panelStates);
if (panelStates.size() > 0) {
outState.putSparseParcelableArray(PANELS_TAG, panelStates);
}
...
return outState;
}
这里主要看注释 1
// View.java
public void saveHierarchyState(SparseArray<Parcelable> container) {
dispatchSaveInstanceState(container);
}
// ViewGroup.java 遍历所有子View调用其 dispatchSaveInstanceState 方法。
@Override
protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
super.dispatchSaveInstanceState(container);
final int count = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
View c = children[i];
if ((c.mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED) {
c.dispatchSaveInstanceState(container);
}
}
}
// View.java
protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
// 调用 onSaveInstanceState 保存状态
Parcelable state = onSaveInstanceState();
...
}
}
如果 View 存在 id,且没有禁用状态保存,都会回调其 onSaveInstanceState() 方法。 EditText 在我们不进行手动状态保存时,其文字依然可以保持,就是因为其父类 TextView 重写了 onSaveInstanceState 方法,完成状态的保存。对于有些 View 状态没有恢复就是因为其没有重写 onSaveInstanceState 方法。
前面知道 Fragment 的状态保存是调用了 FragmentController 的 saveAllState 方法,这里就一睹风采。
// FragmentController.java
public Parcelable saveAllState() {
return mHost.mFragmentManager.saveAllState();
}
mHost 就是 Activity 的内部类 HostCallbacks。 mFragmentManager 在其父类中创建,是FragmentManagerImpl。 FragmentManagerImpl 是 FragmentManager 的具体实现类。
FragmentManagerImpl.java
Parcelable saveAllState() {
...
// 保存所有存活的 Fragment
int N = mActive.size();
FragmentState[] active = new FragmentState[N];
boolean haveFragments = false;
for (int i=0; i<N; i++) {
Fragment f = mActive.valueAt(i);
if (f != null) {
haveFragments = true;
FragmentState fs = new FragmentState(f);
active[i] = fs;
...
}
}
...
int[] added = null;
BackStackState[] backStack = null;
// 保存添加过的 Fragment
N = mAdded.size();
if (N > 0) {
added = new int[N];
for (int i=0; i<N; i++) {
added[i] = mAdded.get(i).mIndex;
}
}
// 保存回退栈
if (mBackStack != null) {
N = mBackStack.size();
if (N > 0) {
backStack = new BackStackState[N];
for (int i=0; i<N; i++) {
backStack[i] = new BackStackState(this, mBackStack.get(i));
}
}
}
FragmentManagerState fms = new FragmentManagerState();
fms.mActive = active;
fms.mAdded = added;
fms.mBackStack = backStack;
fms.mNextFragmentIndex = mNextFragmentIndex;
if (mPrimaryNav != null) {
fms.mPrimaryNavActiveIndex = mPrimaryNav.mIndex;
}
saveNonConfig();
return fms;
}
直接看 ActivityThread 的 performLaunchActivity
ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
if (activity != null) {
...
// 1. 回调 Activity 的 onCreate 方法
mInstrumentation.callActivityOnCreate(activity, r.state);
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
// 2. 回调 Activity 的 onStart 方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
// 3. 回调 Activity 的 onRestoreInstanceState 方法
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
r.paused = true;
// 4. 将 Activity 的信息记录对象存到 mActivities 中。
mActivities.put(r.token, r);
}...
return activity;
}
可见 onRestoreInstanceState 会在存储数据不为空的情况下会被调用,调用顺序是在 onStart 方法之后,onResume 之前。
参考
Android源码解析(二十四)–>onSaveInstanceState执行时机