一、FragmentActivity#onSaveInstanceState
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
markFragmentsCreated();
// 调用FragmentController的saveAllState保存状态,将状态数据保存在Parcelable对象中
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mPendingFragmentActivityResults.size() > 0) {
outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex);
int[] requestCodes = new int[mPendingFragmentActivityResults.size()];
String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()];
for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) {
requestCodes[i] = mPendingFragmentActivityResults.keyAt(i);
fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i);
}
outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes);
outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos);
}
}
1.onSaveInstanceState方法的调用触发流程
该方法的调用,是从ActivityThread触发的。比如在ActivityThread触发调用Activity的pause生命周期的时候,会调用performPauseActivity方法,在这里会执行下面代码:
(1)ActivityThread
// 判断是否需要保存状态
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
callActivityOnSaveInstanceState(r);
}
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);
}
}
(2)Instrumentation
public void callActivityOnSaveInstanceState(@NonNull Activity activity,
@NonNull Bundle outState) {
activity.performSaveInstanceState(outState);
}
public void callActivityOnSaveInstanceState(@NonNull Activity activity,
@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
activity.performSaveInstanceState(outState, outPersistentState);
}
(3)Activity
final void performSaveInstanceState(@NonNull Bundle outState) {
dispatchActivityPreSaveInstanceState(outState);
// 在这里执行Activity的状态保存的方法,也就是最上面看到的那个方法
onSaveInstanceState(outState);
saveManagedDialogs(outState);
mActivityTransitionState.saveState(outState);
storeHasCurrentPermissionRequest(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
dispatchActivityPostSaveInstanceState(outState);
}
或者是在ActivityThread的performStopActivityInner方法进行状态保存,最终依然是调用到ActivityThread#callActivityOnSaveInstanceState方法。
2.继续续分析onSaveInstanceState方法:
(1)FragmentActivity#onSaveInstanceState
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
markFragmentsCreated();
// 调用FragmentController的saveAllState保存状态,将状态数据保存在Parcelable对象中
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mPendingFragmentActivityResults.size() > 0) {
outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex);
int[] requestCodes = new int[mPendingFragmentActivityResults.size()];
String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()];
for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) {
requestCodes[i] = mPendingFragmentActivityResults.keyAt(i);
fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i);
}
outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes);
outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos);
}
}
在这里离,首先会调用FragmentController的saveAllState方法保存Fragment的当前的状态,而FragmentController的saveAllState方法的内部,其实是调用了HostCallbacks中的FragmentManager的saveAllState方法。
(2)FragmentManager#saveAllState
Parcelable saveAllState() {
// 确保所有待处理的操作已经获取到最新的状态信息
// 该方法是将延迟队列中的事务出队并且启动
forcePostponedTransactions();
// 结束所有Fragment的动画
endAnimatingAwayFragments();
// 执行所有待处理的操作
execPendingActions(true);
// 修改状态标志,改成正在保存状态
// 则在commit的时候,会调用checkStateLoss()方法判断是否正在做保存
// 即在commit异步提交的时候,会执行到enqueueAction方法,然后根据标志位判断是否允许状态丢失
// 如果是不允许,则会判断当前commit的时候是否正在做状态保存
// 如果是正在做状态保存,则会抛出异常Can not perform this action after onSaveInstanceState
mStateSaved = true;
// 收集所有的活动Fragment,并且保存活动的Fragment的各种状态,比如View的状态等
ArrayList<FragmentState> active = mFragmentStore.saveActiveFragments();
if (active.isEmpty()) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "saveAllState: no fragments!");
return null;
}
// 这里保存的其实是每个Fragment对应的标志id,其实就是Fragment中的mWho值
ArrayList<String> added = mFragmentStore.saveAddedFragments();
// 保存回退栈中的Fragment
BackStackState[] backStack = null;
if (mBackStack != null) {
int size = mBackStack.size();
if (size > 0) {
backStack = new BackStackState[size];
for (int i = 0; i < size; i++) {
backStack[i] = new BackStackState(mBackStack.get(i));
if (isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "saveAllState: adding back stack #" + i
+ ": " + mBackStack.get(i));
}
}
}
}
// FragmentManagerState是Parcelable的接口实现类
FragmentManagerState fms = new FragmentManagerState();
fms.mActive = active;
fms.mAdded = added;
fms.mBackStack = backStack;
fms.mBackStackIndex = mBackStackIndex.get();
if (mPrimaryNav != null) {
fms.mPrimaryNavActiveWho = mPrimaryNav.mWho;
}
return fms;
}
(3)FragmentStore#saveActiveFragments
@NonNull
ArrayList<FragmentState> saveActiveFragments() {
ArrayList<FragmentState> active = new ArrayList<>(mActive.size());
for (FragmentStateManager fragmentStateManager : mActive.values()) {
if (fragmentStateManager != null) {
Fragment f = fragmentStateManager.getFragment();
FragmentState fs = fragmentStateManager.saveState();
active.add(fs);
if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "Saved state of " + f + ": " + fs.mSavedFragmentState);
}
}
}
return active;
}
(4)FragmentStateManager#saveState
@NonNull
FragmentState saveState() {
FragmentState fs = new FragmentState(mFragment);
if (mFragment.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
// 这里就是保存Fragment的基本状态,比如View
fs.mSavedFragmentState = saveBasicState();
if (mFragment.mTargetWho != null) {
if (fs.mSavedFragmentState == null) {
fs.mSavedFragmentState = new Bundle();
}
fs.mSavedFragmentState.putString(
TARGET_STATE_TAG,
mFragment.mTargetWho);
if (mFragment.mTargetRequestCode != 0) {
fs.mSavedFragmentState.putInt(
TARGET_REQUEST_CODE_STATE_TAG,
mFragment.mTargetRequestCode);
}
}
} else {
fs.mSavedFragmentState = mFragment.mSavedFragmentState;
}
return fs;
}
(5)FragmentStateManager#saveBasicState
private Bundle saveBasicState() {
Bundle result = new Bundle();
// 这里是保存Fragment中的子Fragment的状态的
mFragment.performSaveInstanceState(result);
// 分发状态保存结果
mDispatcher.dispatchOnFragmentSaveInstanceState(mFragment, result, false);
if (result.isEmpty()) {
result = null;
}
if (mFragment.mView != null) {
// 保存View的状态
saveViewState();
}
if (mFragment.mSavedViewState != null) {
if (result == null) {
result = new Bundle();
}
// 其实View的状态也是转成一个Parcelable
// 并且保存在了一个SparseArray中,因为View会有子View
result.putSparseParcelableArray(
VIEW_STATE_TAG, mFragment.mSavedViewState);
}
// 保存Fragment的显示状态
if (!mFragment.mUserVisibleHint) {
if (result == null) {
result = new Bundle();
}
// Only add this if it's not the default value
result.putBoolean(USER_VISIBLE_HINT_TAG, mFragment.mUserVisibleHint);
}
return result;
}
(6)FragmentStateManager#saveViewState
void saveViewState() {
if (mFragment.mView == null) {
return;
}
SparseArray<Parcelable> mStateArray = new SparseArray<>();
// 这里其实是调用View的状态分发保存,将要保存状态的消息分发给其子View
// 然后保存每个View的状态信息到mStateArray中。
// 这里其实就是分别调用每一层级的View的onSaveInstanceState方法
// 这样就可以将每个View视图保存成一个Parcelable,并且保存在对应的SparseArray集合中
mFragment.mView.saveHierarchyState(mStateArray);
if (mStateArray.size() > 0) {
mFragment.mSavedViewState = mStateArray;
}
}
(7)View#saveHierarchyState
public void saveHierarchyState(SparseArray<Parcelable> container) {
dispatchSaveInstanceState(container);
}
protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
Parcelable state = onSaveInstanceState();
if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
throw new IllegalStateException(
"Derived class did not call super.onSaveInstanceState()");
}
if (state != null) {
// Log.i("View", "Freezing #" + Integer.toHexString(mID)
// + ": " + state);
container.put(mID, state);
}
}
}
3.Fragment的状态恢复
Fragment的状态恢复,其实是在FragmentActivity的onCreate刚执行的时候就会判断savedInstanceState是否不为null,然后进行恢复的。
网友评论