最近在开发过程中发现自己对Fragment的管理原理理解的很模糊,于是以Android-28为基础,对Fragment的管理做了一下简单梳理,记录在此,方便后面查阅。
本文主要弄清下面几个问题:
- Transation()到底做了什么事情
- Replace()操作,Fragment到底是什么显示出来的。
- popBackStack()上一个Fragment是如何恢复的。
一、事务Transation到底做了哪些事情
首先明确一点:所有可以使用Fragment的Activity都是FragmentActivity的子类。因为只有在FragmentActivity中才有FragmentManager。而Fragment是由FragmentManager来管理的。
getFragmentManager()获取到的FragmentManager支持原生的Fragment,
getSupportFragmentManager()支持的是v4包的Fragment。
1.1 FragmentManagerImpl 是 FragmentManager的实现类
在FragmentAactivity这个类下面,当我们调用getSupportManager的时候
public class FragmentActivity extends BaseFragmentActivityJB implements
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompatApi23.RequestPermissionsRequestCodeValidator {
···
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
···
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
···
}
我们可以看到FragmentActivity里面有一个FragmentController,这个FragmentController定义了所有对Fragment的管理操作,包括我们的Activity在onCreate,onResume,onDestroy等各种生命周期或回调对Fragment的影响,都是由这个类来控制的。
public class FragmentController {
private final FragmentHostCallback> mHost;
/**
* Returns a {@link FragmentController}.
*/
public static final FragmentController createController(FragmentHostCallback> callbacks) {
return new FragmentController(callbacks);
}
/**
* Returns a {@link FragmentManager} for this controller.
*/
public FragmentManager getSupportFragmentManager() {
//获取到FragmentManager对象
return mHost.getFragmentManagerImpl();
}
FragmentHostCallback是一个抽象类,负责调用各种各样的回调。
HostCallbacks是FragmentActivity里面的一个继承FragmentHostCallback的内部类。下面我们来看看FragmentHostCallback的默认实现
public abstract class FragmentHostCallback extends FragmentContainer {
private final Activity mActivity;
···
// 实例化FragmentManager对象,FragmentManagerImpl是继承自FragmentManager抽象类的,对FragmentManager的各种方法提供具体实现
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
···
}
至此我们找到了Fragment的实现类FragmentManagerImpl
FragmentManagerImpl里面的具体实现就是有关Fragment是如何运行的,各种各样的生命周期,判断Fragment的不同状态,切换状态,Transaction只是用作记录对Fragment的操作记录,最终调用commit的时候,实际上调用的还是FragmentManagerImpl的方法
1.2、 FragmentTransaction 是操作Fragment的桥梁。
每次我们对Fragment进行操作 都是通过FragmentTransaction这个类来实现。
FragmentTransaction的一些常用使用方式:
//添加Fragment到FragmentList中
private void addFragment(Fragment fragment, String tag){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.fragment_container,fragment,tag);
transaction.commit();
}
// 清空fragmentList的所有Fragment,替换成新的Fragment,注意Fragment里面的坑
private void replaceFragment(Fragment fragment, String tag){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment_container,fragment,tag);
transaction.commit();
}
//移除指定的Fragment
private void removeFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
//把Fragment设置成显示状态,但是并没有添加到FragmentList中
private void showFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.show(fragment);
transaction.commit();
}
//把Fragment设置成显示状态,但是并没有添加到FragmentList中
private void hideFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.hide(fragment);
transaction.commit();
}
// 效果和show相近,创建视图,添加到containerid指定的Added列表,FragmentList依然保留,但是会引起生命周期的变化
private void attachFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.attach(fragment);
transaction.commit();
}
// 效果和hide相近,清除视图,从containerid指定的Added列表移除,FragmentList依然保留,但是会引起生命周期的变化
private void detachFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.detach(fragment);
transaction.commit();
}
核心敲重点:
Transaction只是用作记录对Fragment的操作记录,最终调用commit的时候,实际上调用的还是FragmentManagerImpl的方法
FragmentManager.beginTransaction() 返回的是一个BackStackRecord的实例,而BackStackRecord继承自FragmentTransaction
// FragmentManager 的实现类
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
···
@Override
public FragmentTransaction beginTransaction() {
// 每次的FragmentTransaction都是独立的
return new BackStackRecord(this);
}
···
}
// Transaction的实现类
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
// 初始化的时候传入FragmentManagerImpl 的实例
public BackStackRecord(FragmentManagerImpl manager) {
mManager = manager;
}
@Override
public int commit() {
//返回栈id,要是不添加进栈,返回-1
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
// 提交以后无法再次提交
if (mCommitted) throw new IllegalStateException("commit already called");
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Commit: " + this);
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", null, pw, null);
}
mCommitted = true;
//是否要添加到回退栈
if (mAddToBackStack) {
// 在回退栈中分配栈ID
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
//执行这个Transaction
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
}
FragmentTransaction 支持一系列的操作
#将一个fragment实例添加到Activity里面指定id的容器中
add(Fragment fragment, String tag)
add(int containerViewId, Fragment fragment)
add(int containerViewId, Fragment fragment, String tag);
#将一个fragment实例从FragmentManager的FragmentList中移除
remove(Fragment fragment);
#只控制Fragment的隐藏
hide(Fragment fragment)
#只控制Fragment的显示
show(Fragment fragment)
#清除视图,从containerid指定的Added列表移除,FragmentList依然保留
detach(Fragment fragment)
#创建视图,添加到containerid指定的Added列表,FragmentList依然保留
attach(Fragment fragment)
#替换containerViewId中的fragment,它会把containerViewId中所有fragment删除,然后添加当前的fragment
replace(int containerViewId, Fragment fragment)
replace(int containerViewId, Fragment fragment, String tag)
FragmentTransaction 其实就是一个容器,内部维护一个mOps数组,执行add(),remove(),replace()操作时,所做的就是讲这些操作封装成Op对象保存在mOps数组中。
public abstract class FragmentTransaction {
static final int OP_NULL = 0;
static final int OP_ADD = 1;
static final int OP_REPLACE = 2;
static final int OP_REMOVE = 3;
static final int OP_HIDE = 4;
static final int OP_SHOW = 5;
static final int OP_DETACH = 6;
static final int OP_ATTACH = 7;
static final int OP_SET_PRIMARY_NAV = 8;
static final int OP_UNSET_PRIMARY_NAV = 9;
static final int OP_SET_MAX_LIFECYCLE = 10;
static final class Op {
int mCmd;
Fragment mFragment;
Op() {
}
Op(int cmd, Fragment fragment) {
this.mCmd = cmd;
this.mFragment = fragment;
}
}
ArrayList mOps = new ArrayList<>();
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
/**
* Calls {@link #add(int, Fragment, String)} with a 0 containerViewId.
*/
@NonNull
public FragmentTransaction add(@NonNull Fragment fragment, @Nullable String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
@NonNull
public FragmentTransaction remove(@NonNull Fragment fragment) {
addOp(new Op(OP_REMOVE, fragment));
return this;
}
}
当执行FragmentTransaction.commit时,最终会调用FragmentManager.enqueueAction(),将BackStackRecord加入到FragmentManager的一个执行队列中,这个操作队列会在主线程中顺序被执行。
final class BackStackRecord{
@Override
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Commit: " + this);
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", pw);
pw.close();
}
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
}
二、BackStackRecord的执行
BackStackRecord加入到FragmentManager队列中是如何被执行的,Fragment又是如何显示出来的呢?(add操作)
FragmentManagerImpl类
/**
* Adds an action to the queue of pending actions.
*
* @param action the action to add
* @param allowStateLoss whether to allow loss of state information
* @throws IllegalStateException if the activity has been destroyed
*/
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mHost == null) {
if (allowStateLoss) {
// This FragmentManager isn't attached, so drop the entire transaction.
return;
}
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<>();
}
mPendingActions.add(action);
scheduleCommit();
}
}
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);
updateOnBackPressedCallbackEnabled();
}
}
}
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
/**
* Only call from main thread!
*/
public boolean execPendingActions() {
ensureExecReady(true);
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
return didSomething;
}
private void removeRedundantOperationsAndExecute(ArrayList records,ArrayList isRecordPop) {
executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
}
private void executeOpsTogether(ArrayList records,
ArrayList isRecordPop, int startIndex, int endIndex) {
final boolean allowReordering = records.get(startIndex).mReorderingAllowed;
boolean addToBackStack = false;
if (mTmpAddedFragments == null) {
mTmpAddedFragments = new ArrayList<>();
} else {
mTmpAddedFragments.clear();
}
mTmpAddedFragments.addAll(mAdded);
Fragment oldPrimaryNav = getPrimaryNavigationFragment();
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (!isPop) {
//注释一:将ops操作 拆解为基本操作的序列
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
} else {
oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav);
}
addToBackStack = addToBackStack || record.mAddToBackStack;
}
mTmpAddedFragments.clear();
executeOps(records, isRecordPop, startIndex, endIndex);
}
private static void executeOps(ArrayList records,
ArrayList 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);
boolean moveToState = i == (endIndex - 1);
//注释二:出栈操作,执行executePopOps
record.executePopOps(moveToState);
} else {
record.bumpBackStackNesting(1);
//注释三:入栈操作,执行executeOps()
record.executeOps();
}
}
}
- 注释一:record.expandOps()会将ops操作 拆解为更简单的基本操作序列,如replace()操作,会被拆解为N个Remove+1个Add操作,保存在mOps数组中。
- 注释二:如果当前BackStackRecord是出栈操作,则执行record.executePopOps()
- 注释三:如果当前BackStackRecord是入栈操作,则执行record.executeOps()
下面我们重点看一下BackStackRecord的这三个方法
2.1、 BackStackRecord.expandOps():
expandOps的主要作用扩展Op操作,将原始是Ops操作扩展成更基本的Ops序列,它会修改FragmentManagetImpl的mAdded数组和oldPrimaryNav
/**
* Expands all meta-ops into their more primitive equivalents. This must be called prior to
* {@link #executeOps()} or any other call that operations on mOps for forward navigation.
* It should not be called for pop/reverse navigation operations.
*
* Removes all OP_REPLACE ops and replaces them with the proper add and remove
* operations that are equivalent to the replace.
*
* Adds OP_UNSET_PRIMARY_NAV ops to match OP_SET_PRIMARY_NAV, OP_REMOVE and OP_DETACH
* ops so that we can restore the old primary nav fragment later. Since callers call this
* method in a loop before running ops from several transactions at once, the caller should
* pass the return value from this method as the oldPrimaryNav parameter for the next call.
* The first call in such a loop should pass the value of
* {@link FragmentManager#getPrimaryNavigationFragment()}.
*
* @param added Initialized to the fragments that are in the mManager.mAdded, this
* will be modified to contain the fragments that will be in mAdded
* after the execution ({@link #executeOps()}.
* @param oldPrimaryNav The tracked primary navigation fragment as of the beginning of
* this set of ops
* @return the new oldPrimaryNav fragment after this record's ops would be run
*/
@SuppressWarnings("ReferenceEquality")
Fragment expandOps(ArrayList added, Fragment oldPrimaryNav) {
for (int opNum = 0; opNum < mOps.size(); opNum++) {
final Op op = mOps.get(opNum);
switch (op.mCmd) {
case OP_ADD:
case OP_ATTACH:
//(1)ADD和ATTACH方法,仅将mFragment添加到mAdded数组
added.add(op.mFragment);
break;
case OP_REMOVE:
case OP_DETACH: {
//(2)REMOVE和DETACH操作,将mFragment从added数组移除,并插入OP_UNSET_PRIMARY_NAV操作,将oldPrimaryNav移除
added.remove(op.mFragment);
if (op.mFragment == oldPrimaryNav) {
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.mFragment));
opNum++;
oldPrimaryNav = null;
}
}
break;
case OP_REPLACE: {
//(3)REPLACE 将added数组中,所有mContainerId匹配的Frament移除,然后再j将当前Frament添加。replace操作 转变成了REMOVE*N+ADD的序列
final Fragment f = op.mFragment;
final int containerId = f.mContainerId;
boolean alreadyAdded = false;
for (int i = added.size() - 1; i >= 0; i--) {
final Fragment old = added.get(i);
if (old.mContainerId == containerId) {
if (old == f) {
alreadyAdded = true;
} else {
// This is duplicated from above since we only make
// a single pass for expanding ops. Unset any outgoing primary nav.
if (old == oldPrimaryNav) {
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, old));
opNum++;
oldPrimaryNav = null;
}
final Op removeOp = new Op(OP_REMOVE, old);
removeOp.mEnterAnim = op.mEnterAnim;
removeOp.mPopEnterAnim = op.mPopEnterAnim;
removeOp.mExitAnim = op.mExitAnim;
removeOp.mPopExitAnim = op.mPopExitAnim;
mOps.add(opNum, removeOp);
added.remove(old);
opNum++;
}
}
}
if (alreadyAdded) {
mOps.remove(opNum);
opNum--;
} else {
op.mCmd = OP_ADD;
added.add(f);
}
}
break;
//(4)SET_PRIMARY_NAV 操作,更新oldPrimaryNav的值
case OP_SET_PRIMARY_NAV: {
// It's ok if this is null, that means we will restore to no active
// primary navigation fragment on a pop.
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, oldPrimaryNav));
opNum++;
// Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
oldPrimaryNav = op.mFragment;
}
break;
}
}
return oldPrimaryNav;
}
- (1)ADD和ATTACH方法,仅将mFragment添加到mAdded数组
- (2)REMOVE和DETACH操作,将mFragment从added数组移除,并插入OP_UNSET_PRIMARY_NAV操作,将oldPrimaryNav移除。
- (3)REPLACE 将added数组中,所有mContainerId匹配的Frament移除,然后再j将当前Frament添加。replace操作 转变成了REMOVE*N+ADD的序列。
- (4)SET_PRIMARY_NAV 操作,更新oldPrimaryNav的值
2.2、 BackStackRecord.executeOps() 入栈操作
当Fragment入栈时,会执行BackStackRecord.executeOps()方法
executeOps方法中,将Op操作 都代理到了FragmentManagerImpl对应的方法。
void executeOps() {
final int numOps = mOps.size();
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
final Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(mTransition, mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mEnterAnim);
mManager.addFragment(f, false);
break;
case OP_REMOVE:
f.setNextAnim(op.mExitAnim);
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setNextAnim(op.mExitAnim);
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mEnterAnim);
mManager.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mExitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mEnterAnim);
mManager.attachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mCurrentMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
if (!mReorderingAllowed && op.mCmd != OP_ADD && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed) {
// Added fragments are added at the end to comply with prior behavior.
mManager.moveToState(mManager.mCurState, true);
}
}
执行OP_ADD时 会顺序执行
- FragmentManagerImpl.addFragment()
- FragmentManagerImpl.moveToState()
- FragmentManagerImpl.moveFragmentToExpectedState()
- FragmentManagerImpl.moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive)
addFragment中的核心操作 就是将将Fragmet加入到mAdded数组,同时修改Fragment对应的标志位
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (DEBUG) Log.v(TAG, "add: " + fragment);
makeActive(fragment);
if (!fragment.mDetached) {
//将Fragmet加入到mAdded数组
synchronized (mAdded) {
mAdded.add(fragment);
}
//修改frament中的标志位
fragment.mAdded = true;
fragment.mRemoving = false;
if (moveToStateNow) {
moveToState(fragment);
}
}
}
操作二:调用moveToState()方法
moveFragmentToExpectedState->moveToState()
2.3、 FragmentManagerImpl.moveToState() 执行Fragment的状态切换
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;
}
// Don't allow the Fragment to go above its max lifecycle state
// Ensure that Fragments are capped at CREATED instead of ACTIVITY_CREATED.
if (f.mMaxState == Lifecycle.State.CREATED) {
newState = Math.min(newState, Fragment.CREATED);
} else {
newState = Math.min(newState, f.mMaxState.ordinal());
}
//如果newState > Fragment当前的状态
if (f.mState <= newState) {
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.mFragmentManager;
//(1)执行Fragment.attach()
f.performAttach();
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
//(2)执行Fragmet.onCreate()
if (!f.mIsCreated) {
dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
}
// fall through
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
//(1)提取Fragment的ContainerId 对应的ViewGroup
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
// (2) 调用Fragment的onCreateView()绘制Fragment中的View
f.mContainer = container;
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
//(3)将Framgnet中的View 添加到ContrainerView当中
if (container != null) {
container.addView(f.mView);
}
if (f.mHidden) {
f.mView.setVisibility(View.GONE);
}
//(4)调用Fragment的OnViewCreated()
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
false);
f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
&& f.mContainer != null;
} else {
f.mInnerView = null;
}
}
//(5)调用Fragment的onActivityCreated()
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
// fall through
case Fragment.ACTIVITY_CREATED:
//(1) 调用Fragment.onStart()
if (newState > Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.performStart();
dispatchOnFragmentStarted(f, false);
}
// fall through
case Fragment.STARTED:
//(1) 调用Fragment.onResume()
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) {
... //执行一些列反向的操作
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
f.performPause();
dispatchOnFragmentPaused(f, false);
}
// fall through
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
dispatchOnFragmentStopped(f, false);
}
// fall through
}
}
if (f.mState != newState) {
f.mState = newState;
}
}
Fragment 有以下几个状态:
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3; // Created and started, not resumed.
static final int RESUMED = 4; // Created started and resumed.
moveToState()方法 将Fragment由当前的mState状态切换为newState状态。 以正向声明周期为例, executePopOps()是Fragment出栈时的操作,是入栈操作的逆操作。 假设Actvity中当前正在显示FragmentA,此时在同一个ContainerID上执行replace(FragmentB())。执行过程如下: 至此FragmentB 被添加到Activity的View树中,显示出来。 FragmentManager中有一个mBackStack数组,承载了加入回退栈中的FragmentTransaction操作 调用FragmentTransaction.addToBackStack(),便将自己加入到回退栈中。 当点击Android的回退键时,会调用Activity的onBackPressed()方法。最终调用fragmentManager.popBackStackImmediate()方法。 最终会调用到executeOps()方法,因为是回退操作,isRecordPop == true,会执行record.executePopOps(moveToState); executePopOps()执行原transaction操作的反向操作,如原操作是OP_ADD操作,则实际执行OP_REMOVE操作;操作是OP_REMOVE操作,则执行OP_ADD操作。 注意:FragmenetTransantion.replace()操作,执行时会被拆分成remove+add操作;相应的,回退时,顺序执行执行remove和add操作。 https://www.jianshu.com/p/1ee67d935757
当newState>Fragment.mState 进行Fraggment的正向生命周期,当newState
Fragment.onCreate()
Fragment.onAttach()
(1) 提取Fragment的ContainerId 对应的ViewGroup
(2) 调用Fragment的onCreateView()获取Fragment中的的View
(3) 将Framgnet中的View 添加到ContrainerView当中
(4) 调用Fragment的OnViewCreated()
(5) 调用Fragment的onActivityCreated()
Fragment.onStart()
2.4、BackStackRecord.executePopOps()
void executePopOps(boolean moveToState) {
for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
final Op op = mOps.get(opNum);
Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mPopExitAnim);
mManager.removeFragment(f);
break;
case OP_REMOVE:
f.setNextAnim(op.mPopEnterAnim);
mManager.addFragment(f, false);
break;
case OP_HIDE:
f.setNextAnim(op.mPopEnterAnim);
mManager.showFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mPopExitAnim);
mManager.hideFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mPopEnterAnim);
mManager.attachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mPopExitAnim);
mManager.detachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mOldMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
if (!mReorderingAllowed && op.mCmd != OP_REMOVE && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed && moveToState) {
mManager.moveToState(mManager.mCurState, true);
}
}
2.5、总结一下执行replace()时 Fragment的View是如何显示出来的
- FragmentA执行OP_REMOVE 被移除
- FragmentB执行OP_ADD 被添加
当Fragment.mState == CREATED 时,执行一下操作
(1) 提取Fragment的ContainerId 对应的ViewGroup
(2) 调用Fragment的onCreateView()获取Fragment中的的View
(3) 将Framgnet中的View 添加到ContrainerView当中
(4) 调用Fragment的OnViewCreated()
(5) 调用Fragment的onActivityCreated()
三、Fragment是如何回退的。
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2
ArrayList
@NonNull
public FragmentTransaction addToBackStack(@Nullable 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 void onBackPressed() {
if (mActionBar != null && mActionBar.collapseActionView()) {
return;
}
FragmentManager fragmentManager = mFragments.getFragmentManager();
if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
finishAfterTransition();
}
}
private boolean popBackStackImmediate(String name, int id, int flags) {
//(1)popBackStackState 负责遍历mBackStack回退栈,将回退栈中的操作整理填充到this.mTmpRecords,并记录是否是pop回退操作(保留在this.mTmpIsPop)中
boolean executePop = this.popBackStackState(this.mTmpRecords, this.mTmpIsPop, name, id, flags);
if (executePop) {
this.mExecutingActions = true;
try {
//(2) 根据this.mTmpRecords和this.mTmpIsPop 执行具体的transantion
this.removeRedundantOperationsAndExecute(this.mTmpRecords, this.mTmpIsPop);
} finally {
this.cleanupExec();
}
}
this.doPendingDeferredStart();
this.burpActive();
return executePop;
}
private static void executeOps(ArrayList
void executePopOps(boolean moveToState) {
for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
final Op op = mOps.get(opNum);
Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mPopExitAnim);
mManager.removeFragment(f);
break;
case OP_REMOVE:
f.setNextAnim(op.mPopEnterAnim);
mManager.addFragment(f, false);
break;
case OP_HIDE:
f.setNextAnim(op.mPopEnterAnim);
mManager.showFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mPopExitAnim);
mManager.hideFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mPopEnterAnim);
mManager.attachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mPopExitAnim);
mManager.detachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mOldMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
if (!mReorderingAllowed && op.mCmd != OP_REMOVE && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed && moveToState) {
mManager.moveToState(mManager.mCurState, true);
}
}
四、参考文章:
https://www.cnblogs.com/punkisnotdead/p/4974527.html