源码解析Fragment 返回栈原理
系列
Fragment (一):Fragment使用详解
Fragment (二):Activity 和Fragment 的异常销毁、状态保存和恢复机制
Fragment (三):源码解析Fragment 返回栈原理
返回栈涉及的类
在看本文前需要熟悉Fragment 的使用,不清楚的可先看:Fragment使用详解
本文源码都是都是v25 的support v4 包下的源码。
基本操作:getFragmentManager().beginTransaction().add(R.id.container, fragment).addToBackStack(null).commit();
getFragmentManager():实际返回值是FragmentManagerImpl 对象。
beginTransaction():实际返回值是BackStackRecord 对象。
BackStackRecord.Op
代表Fragment 事务中的一次操作,如add、remove等。BackStackRecord
一个BackStackRecord 代表一次Fragment 事务。
BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator 实现了OpGenerator
Field:
1、ArrayList<BackStackRecord.Op> mOps:保存一次Fragment 事务的所有Op 操作。
2、FragmentManagerImpl mManager:保存getFragmentManager() 的返回值。FragmentManagerImpl.OpGenerator
相当于BackStackRecord。一个OpGenerator 对象能产生相应的一个BackStackRecord 对象,该BackStackRecord 对象可能是OpGenerator 对象本身也可能来自返回栈。FragmentManagerImpl
Field:
1、ArrayList<FragmentManagerImpl.OpGenerator> mPendingActions:存放当前尚未执行的所有事务,用于产生mTmpRecords 和mTmpIsPop。
2、ArrayList<BackStackRecord> mTmpRecords:存放当前尚未执行的所有事务,由mPendingActions 转化而来。
3、ArrayList<Boolean> mTmpIsPop:mTmpRecords 中对应下标下的事务是否是出栈。
4、ArrayList<BackStackRecord> mBackStack:返回栈,存放mTmpRecords 中进栈的事务。
5、ArrayList<Fragment> mAdded:存放前台Fragment,即已调用了add() 但尚未进入返回栈或被被销毁的Fragment。
6、ArrayList<Fragment> mActive:存放前台Fragment 和返回栈中的Fragment。
7、ArrayList<Fragment> mTmpAddedFragments:临时的mAdded 。
看源码前先了解下:
1、Fragment 的各种状态:
static final int INITIALIZING = 0; // Not yet created.销毁。
static final int CREATED = 1; // Created.没有视图但fragment已创建,比如:fragment处于返回栈中。
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.宿主Activity已创建完毕,就是fragment生命周期已调用到onActivityCreated(),已创建视图。
static final int STOPPED = 3; // Fully created, not started.不显示
static final int STARTED = 4; // Created and started, not resumed.不聚焦
static final int RESUMED = 5; // Created started and resumed.聚焦
事务提交
流程
- BackStackRecord:addToBackStack() //若调用则标志事务进栈,否则不进栈。
- BackStackRecord:commit()
- BackStackRecord:commitInternal()
- FragmentManagerImpl:enqueueAction() //BackStackRecord加入mPendingActions。
- FragmentManagerImpl:generateOpsForPendingActions() //mPendingActions转换为mTmpRecords 和mTmpIsPop。
- FragmentManagerImpl:executeOpsTogether() //遍历mTmpRecords。1、将Op是replace 的替换为多个remove 和一个add。2、执行所有Op,更新mAdded 和mActive。每个事务的最后一个Op时,对mAdded 和mActive 中所有Fragment 切换生命周期到预期的状态,同时,在此过程中对每一个从前台退回到返回栈的Fragment调用它的*View 的saveHierarchyState() 保存View状态,对每一个从返回栈出栈变为前台的Fragment调用它的*View的restoreHierarchyState() 恢复View状态。
源码
BackStackRecord:
public FragmentTransaction addToBackStack(String name) {
if (!mAllowAddToBackStack) {
throw new IllegalStateException(
"This FragmentTransaction is not allowed to be added to the back stack.");
}
mAddToBackStack = true;//
mName = name;
return this;
}
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);//该BackStackRecord对象加入mPendingActions
return mIndex;
}
FragmentManagerImpl:
/**
* Adds an action to the queue of pending actions.
*/
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<>();
}
mPendingActions.add(action);//
scheduleCommit();//用UI线程的Handler发送Runnable
}
}
private void scheduleCommit() {
synchronized (this) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);//发送runnable
}
}
}
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
/**
* Only call from main thread!
*/
public boolean execPendingActions() {
ensureExecReady(true);
boolean didSomething = false;
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {//mPendingActions 转换为mTmpRecords 和mTmpIsPop。
mExecutingActions = true;
try {
optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);//优化并处理所有Op
} finally {
cleanupExec();
}
didSomething = true;
}
doPendingDeferredStart();
return didSomething;
}
/**
* Adds all records in the pending actions to records and whether they are add or pop
* operations to isPop. After executing, the pending actions will be empty.
*/
private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isPop) {
int numActions;
synchronized (this) {
if (mPendingActions == null || mPendingActions.size() == 0) {
return false;
}
numActions = mPendingActions.size();
for (int i = 0; i < numActions; i++) {
mPendingActions.get(i).generateOps(records, isPop);
//若该事务是出栈,则从mBackStack 中取出一个事务即BackStackRecord加入mTmpRecords;
//否则,将当前action 加入mTmpRecords,若该事务进栈还要添加到mBackStack中。
}
mPendingActions.clear();//清空
mHost.getHandler().removeCallbacks(mExecCommit);
}
return numActions > 0;
}
private void optimizeAndExecuteOps(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop) {
......
// Force start of any postponed transactions that interact with scheduled transactions:
executePostponedTransaction(records, isRecordPop);
final int numRecords = records.size();
int startIndex = 0;
for (int recordNum = 0; recordNum < numRecords; recordNum++) {
final boolean canOptimize = records.get(recordNum).mAllowOptimization;
if (!canOptimize) {
// execute all previous transactions
if (startIndex != recordNum) {
executeOpsTogether(records, isRecordPop, startIndex, recordNum);
}
// execute all unoptimized pop operations together or one add operation
int optimizeEnd = recordNum + 1;
if (isRecordPop.get(recordNum)) {
while (optimizeEnd < numRecords
&& isRecordPop.get(optimizeEnd)
&& !records.get(optimizeEnd).mAllowOptimization) {
optimizeEnd++;
}
}
executeOpsTogether(records, isRecordPop, recordNum, optimizeEnd);
startIndex = optimizeEnd;
recordNum = optimizeEnd - 1;
}
}
if (startIndex != numRecords) {
executeOpsTogether(records, isRecordPop, startIndex, numRecords);
}
}
/**
* Optimizes a subset of a list of BackStackRecords, all of which either allow optimization or
* do not allow optimization.
*/
private void executeOpsTogether(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
final boolean allowOptimization = records.get(startIndex).mAllowOptimization;
boolean addToBackStack = false;
if (mTmpAddedFragments == null) {
mTmpAddedFragments = new ArrayList<>();
} else {
mTmpAddedFragments.clear();
}
if (mAdded != null) {
mTmpAddedFragments.addAll(mAdded);
}
//遍历mTmpRecords,优化Op操作,根据mTmpAddedFragments 去除不必要的Op操作。
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (!isPop) {
//替换replac操作为多个remove和一个add操作,
//进栈的事务同样也是在这里替换replace操作的,因此该事务出栈时无需再次进行替换。
record.expandReplaceOps(mTmpAddedFragments);
} else {
record.trackAddedFragmentsInPop(mTmpAddedFragments);
}
addToBackStack = addToBackStack || record.mAddToBackStack;
}
mTmpAddedFragments.clear();//用完立刻就清空
if (!allowOptimization) {
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex,
false);
}
executeOps(records, isRecordPop, startIndex, endIndex);//执行所有Op操作
......
if (addToBackStack) {
reportBackStackChanged();//触发监听器
}
}
/**
* Run the operations in the BackStackRecords, either to push or pop.
*/
private static void executeOps(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
for (int i = startIndex; i < endIndex; i++) {
final BackStackRecord record = records.get(i);
final boolean isPop = isRecordPop.get(i);
if (isPop) {
record.bumpBackStackNesting(-1);
// Only execute the add operations at the end of
// all transactions.
boolean moveToState = i == (endIndex - 1);//最后一个事务时需moveToState 为true,
record.executePopOps(moveToState);//对出栈事务的所有Op进行逆操作
} else {
record.bumpBackStackNesting(1);
record.executeOps();//执行非出栈事务的所有Op操作
}
}
}
BackStackRecord:
/**
* Reverses the execution of the operations within this transaction. The Fragment states will
* only be modified if optimizations are not allowed.
*/
void executePopOps(boolean moveToState) {
for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
final Op op = mOps.get(opNum);
Fragment f = op.fragment;
f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
switch (op.cmd) {
case OP_ADD:
f.setNextAnim(op.popExitAnim);
mManager.removeFragment(f);
break;
case OP_REMOVE:
f.setNextAnim(op.popEnterAnim);
mManager.addFragment(f, false);
break;
case OP_HIDE:
f.setNextAnim(op.popEnterAnim);
mManager.showFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.popExitAnim);
mManager.hideFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.popEnterAnim);
mManager.attachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.popExitAnim);
mManager.detachFragment(f);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
if (!mAllowOptimization && op.cmd != OP_REMOVE) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mAllowOptimization && moveToState) {
//遍历完该事务后执行moveToState()对mAdded 和mActive 中的fragment切换生命周期。
mManager.moveToState(mManager.mCurState, true);
}
}
/**
* Executes the operations contained within this transaction. The Fragment states will only
* be modified if optimizations are not allowed.
*/
void executeOps() {
final int numOps = mOps.size();
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
final Fragment f = op.fragment;
f.setNextTransition(mTransition, mTransitionStyle);
switch (op.cmd) {
case OP_ADD:
f.setNextAnim(op.enterAnim);
mManager.addFragment(f, false);
break;
case OP_REMOVE:
f.setNextAnim(op.exitAnim);
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setNextAnim(op.exitAnim);
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.enterAnim);
mManager.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.exitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.enterAnim);
mManager.attachFragment(f);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
if (!mAllowOptimization && op.cmd != OP_ADD) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mAllowOptimization) {
// Added fragments are added at the end to comply with prior behavior.
//遍历完该事务后执行moveToState()对mAdded 和mActive 中的fragment切换生命周期。
mManager.moveToState(mManager.mCurState, true);
}
}
FragmentManagerImpl:
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (mAdded == null) {
mAdded = new ArrayList<Fragment>();
}
if (DEBUG) Log.v(TAG, "add: " + fragment);
makeActive(fragment);//更新mActive 列表
if (!fragment.mDetached) {
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
mAdded.add(fragment);//更新mAdded 列表
//更新当前fragment 状态
fragment.mAdded = true;
fragment.mRemoving = false;
if (fragment.mView == null) {
fragment.mHiddenChanged = false;
}
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
if (moveToStateNow) {
moveToState(fragment);
}
}
}
//removeFragment()、hideFragment()、showFragment()、detachFragment()、attachFragment()的代码功能类似,都是更新mAdded、mActive以及fragment状态。
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
if (!always && newState == mCurState) {
return;
}
mCurState = newState;
if (mActive != null) {
boolean loadersRunning = false;
// Must add them in the proper order. mActive fragments may be out of order
if (mAdded != null) {
final int numAdded = mAdded.size();
for (int i = 0; i < numAdded; i++) {//遍历mAdded,切换每个fragment的生命周期到预期的状态下
Fragment f = mAdded.get(i);
moveFragmentToExpectedState(f);//切换fragment的生命周期到预期的状态下
if (f.mLoaderManager != null) {
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
}
}
}
// Now iterate through all active fragments. These will include those that are removed
// and detached.
final int numActive = mActive.size();
for (int i = 0; i < numActive; i++) {//遍历mActive,切换每个fragment的生命周期到预期的状态下
Fragment f = mActive.get(i);
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
moveFragmentToExpectedState(f);//切换fragment的生命周期到预期的状态下
if (f.mLoaderManager != null) {
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
}
}
}
......
}
}
/**
* Moves a fragment to its expected final state or the fragment manager's state, depending
* on whether the fragment manager's state is raised properly.
*/
void moveFragmentToExpectedState(Fragment f) {
if (f == null) {
return;
}
//切换到预期状态
int nextState = mCurState;
if (f.mRemoving) {
if (f.isInBackStack()) {//fragment在栈中,想要出栈
nextState = Math.min(nextState, Fragment.CREATED);
} else {
nextState = Math.min(nextState, Fragment.INITIALIZING);
}
}
//据预期的状态执行相应生命周期方法
moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
......
}
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
// Fragments that are not currently added will sit in the onCreate() state.
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
newState = Fragment.CREATED;
}
if (f.mRemoving && newState > f.mState) {
// While removing a fragment, we can't change it to a higher state.
newState = f.mState;
}
// Defer start if requested; don't allow it to move to STARTED or higher
// if it's not already started.
if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
newState = Fragment.STOPPED;
}
if (f.mState < newState) { //状态复原:fragment创建或出栈等
// For fragments that are created from a layout, when restoring from
// state we don't want to allow them to be created until they are
// being reloaded from the layout.
if (f.mFromLayout && !f.mInLayout) {
return;
}
if (f.getAnimatingAway() != null) {
// The fragment is currently being animated... but! Now we
// want to move our state back up. Give up on waiting for the
// animation, move to whatever the final state should be once
// the animation is done, and then we can proceed from there.
f.setAnimatingAway(null);
moveToState(f, f.getStateAfterAnimating(), 0, 0, true);
}
switch (f.mState) {
case Fragment.INITIALIZING:
if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
if (f.mSavedFragmentState != null) {
f.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
FragmentManagerImpl.VIEW_STATE_TAG);
f.mTarget = getFragment(f.mSavedFragmentState,
FragmentManagerImpl.TARGET_STATE_TAG);
if (f.mTarget != null) {
f.mTargetRequestCode = f.mSavedFragmentState.getInt(
FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
}
f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
if (!f.mUserVisibleHint) {
f.mDeferStart = true;
if (newState > Fragment.STOPPED) {
newState = Fragment.STOPPED;
}
}
}
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
f.mCalled = false;
f.onAttach(mHost.getContext());//调用Fragment 的onAttach()。
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
dispatchOnFragmentAttached(f, mHost.getContext(), false);
if (!f.mRetaining) {
f.performCreate(f.mSavedFragmentState);//该方法会触发Fragment 的onCreate()。
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
f.mRetaining = false;
if (f.mFromLayout) {
// For fragments that are part of the content view
// layout, we need to instantiate the view immediately
// and the inflater will take care of adding it.
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
if (Build.VERSION.SDK_INT >= 11) {
ViewCompat.setSaveFromParentEnabled(f.mView, false);
} else {
f.mView = NoSaveStateFrameLayout.wrap(f.mView);
}
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
} else {
f.mInnerView = null;
}
}
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
if (f.mContainerId == View.NO_ID) {
throwException(new IllegalArgumentException(
"Cannot create fragment "
+ f
+ " for a container view with no id"));
}
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
String resName;
try {
resName = f.getResources().getResourceName(f.mContainerId);
} catch (NotFoundException e) {
resName = "unknown";
}
throwException(new IllegalArgumentException(
"No view found for id 0x"
+ Integer.toHexString(f.mContainerId) + " ("
+ resName
+ ") for fragment " + f));
}
}
f.mContainer = container;
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);//会触发Fragment 的onCreateView()。
if (f.mView != null) {
f.mInnerView = f.mView;
if (Build.VERSION.SDK_INT >= 11) {
ViewCompat.setSaveFromParentEnabled(f.mView, false);
} else {
f.mView = NoSaveStateFrameLayout.wrap(f.mView);
}
if (container != null) {
container.addView(f.mView);
}
if (f.mHidden) {
f.mView.setVisibility(View.GONE);
}
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
false);
// Only animate the view if it is visible. This is done after
// dispatchOnFragmentViewCreated in case visibility is changed
f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
&& f.mContainer != null;
} else {
f.mInnerView = null;
}
}
f.performActivityCreated(f.mSavedFragmentState);//会触发Fragment 的onActivityCreated()。
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);//恢复View 状态。
}
f.mSavedFragmentState = null;
}
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
f.mState = Fragment.STOPPED;
}
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.performStart();
dispatchOnFragmentStarted(f, false);
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {//fragment销毁或进栈
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
f.performPause();
dispatchOnFragmentPaused(f, false);
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
dispatchOnFragmentStopped(f, false);
}
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
f.performReallyStop();
}
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
if (f.mView != null) {
// Need to save the current view state if not
// done already.
if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
saveFragmentViewState(f); //保存View 状态。
}
}
f.performDestroyView();
dispatchOnFragmentViewDestroyed(f, false);
if (f.mView != null && f.mContainer != null) {
Animation anim = null;
if (mCurState > Fragment.INITIALIZING && !mDestroyed
&& f.mView.getVisibility() == View.VISIBLE
&& f.mPostponedAlpha >= 0) {
anim = loadAnimation(f, transit, false,
transitionStyle);
}
f.mPostponedAlpha = 0;
if (anim != null) {
final Fragment fragment = f;
f.setAnimatingAway(f.mView);
f.setStateAfterAnimating(newState);
final View viewToAnimate = f.mView;
anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(
viewToAnimate, anim) {
@Override
public void onAnimationEnd(Animation animation) {
super.onAnimationEnd(animation);
if (fragment.getAnimatingAway() != null) {
fragment.setAnimatingAway(null);
moveToState(fragment, fragment.getStateAfterAnimating(),
0, 0, false);
}
}
});
f.mView.startAnimation(anim);
}
f.mContainer.removeView(f.mView);
}
f.mContainer = null;
f.mView = null;
f.mInnerView = null;
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
if (mDestroyed) {
if (f.getAnimatingAway() != null) {
// The fragment's containing activity is
// being destroyed, but this fragment is
// currently animating away. Stop the
// animation right now -- it is not needed,
// and we can't wait any more on destroying
// the fragment.
View v = f.getAnimatingAway();
f.setAnimatingAway(null);
v.clearAnimation();
}
}
if (f.getAnimatingAway() != null) {
// We are waiting for the fragment's view to finish
// animating away. Just make a note of the state
// the fragment now should move to once the animation
// is done.
f.setStateAfterAnimating(newState);
newState = Fragment.CREATED;
} else {
if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
if (!f.mRetaining) {
f.performDestroy();
dispatchOnFragmentDestroyed(f, false);
} else {
f.mState = Fragment.INITIALIZING;
}
f.performDetach();
dispatchOnFragmentDetached(f, false);
if (!keepActive) {
if (!f.mRetaining) {
makeInactive(f);//fragment被销毁需要将fragment从mActive 中删除。
} else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
}
}
}
}
}
}
//fragment切换到新状态
if (f.mState != newState) {
f.mState = newState;
}
}
Fragment:
static final int INITIALIZING = 0; // Not yet created.销毁。
static final int CREATED = 1; // Created.没有视图但fragment已创建,比如:fragment处于返回栈中。
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.宿主Activity已创建完毕,就是fragment生命周期已调用到onActivityCreated(),已创建视图。
static final int STOPPED = 3; // Fully created, not started.不显示
static final int STARTED = 4; // Created and started, not resumed.不聚焦
static final int RESUMED = 5; // Created started and resumed.聚焦
事务出栈
流程
- FragmentManagerImpl:popBackStack()
- FragmentManagerImpl:enqueueAction() //BackStackRecord加入mPendingActions。
- FragmentManagerImpl:generateOpsForPendingActions() //mPendingActions转换为mTmpRecords 和mTmpIsPop。
- FragmentManagerImpl:executeOpsTogether() //遍历mTmpRecords。1、将Op是replace 的替换为多个remove 和一个add。2、执行所有Op,更新mAdded 和mActive。每个事务的最后一个Op时,对mAdded 和mActive 中所有Fragment 切换生命周期到预期状态,同时,在此过程中对每一个从前台退回到返回栈的Fragment调用它的*View 的saveHierarchyState() 保存View状态,对每一个从返回栈出栈变为前台的Fragment调用它的*View的restoreHierarchyState() 恢复View状态。
源码
FragmentManagerImpl:
public void popBackStack() {
enqueueAction(new PopBackStackState(null, -1, 0), false);//注意:这里添加的action不是BackStackRecord。
}
后续的流程更进栈时一样,都是一样的代码。不同的地方只在mPendingActions 转换为mTmpRecords时,因mPendingActions 的元素不一样导致产生的BackStackRecord的来源不一样:
事务提交:mManager.enqueueAction(this, allowStateLoss); 注:this是BackStackRecord。
事务出栈:enqueueAction(new PopBackStackState(null, -1, 0), false);
下面看下BackStackRecord 和PopBackStackState 产生BackStackRecord的区别。
BackStackRecord:
/**
* Implementation of {@link FragmentManagerImpl.OpGenerator}.
* This operation is added to the list of pending actions during {@link #commit()}, and
* will be executed on the UI thread to run this FragmentTransaction.
*/
@Override
public boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Run: " + this);
}
records.add(this);//将自身加入mTmpRecords。
isRecordPop.add(false);
if (mAddToBackStack) {
mManager.addBackStackState(this);//事务加入返回栈
}
return true;
}
FragmentManagerImpl:
private class PopBackStackState implements OpGenerator {
@Override
public boolean generateOps(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop) {
return popBackStackState(records, isRecordPop, mName, mId, mFlags);
}
}
@SuppressWarnings("unused")
boolean popBackStackState(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
String name, int id, int flags) {
if (mBackStack == null) {
return false;
}
if (name == null && id < 0 && (flags & POP_BACK_STACK_INCLUSIVE) == 0) {
int last = mBackStack.size() - 1;
if (last < 0) {
return false;
}
records.add(mBackStack.remove(last));//取出返回栈中事务加入mTmpRecords。
isRecordPop.add(true);
} else {
......
}
return true;
}
总结
事务提交(无论事务是否进栈)和事务出栈的不同之处在于enqueueAction()时传入的入参不同。
事务提交:mManager.enqueueAction(this, allowStateLoss); 注:this是BackStackRecord。
事务出栈:enqueueAction(new PopBackStackState(null, -1, 0), false);
添加action到mPendingActions 之后,后续流程是一样的。
关键:
1. 结构:理解Fragment 处理事务的结构,该结构由mTmpRecords 和 mBackStack 这两个事务列表组成。
1. 更新fragment 列表:同时,还要意识到,每个Op 操作后都会更新mAdded 和mActive 这两个fragment 列表。
1. 切换生命周期:最后都只是对mAdded 和mActive 中的所有fragment 进行生命周期的切换。
推荐阅读
-
Laravel框架源码解析之模型Model原理与用法解析
-
spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
-
Spring MVC源码(三) ----- @RequestBody和@ResponseBody原理解析
-
Mybaits 源码解析 (五)----- 面试源码系列:Mapper接口底层原理(为什么Mapper不用写实现类就能访问到数据库?)
-
Mybaits 源码解析 (三)----- Mapper接口底层原理(为什么Mapper不用写实现类就能访问到数据库?)
-
持久层Mybatis3底层源码分析,原理解析
-
荐 【dubbo源码解析】--- dubbo的服务暴露+服务消费(RPC调用)底层原理深入探析
-
Andorid jar库源码Bolts原理解析
-
Laravel框架源码解析之入口文件原理分析
-
vue源码nextTick使用及原理解析