一、追踪FragmentManager对Fragment操作涉及到方法
getSupportFragmentManager().beginTransaction().remove(Fragment fragment).commit()
BackStackRecord remove(Fragment fragment)
BackStackRecord.commit() // 开始
BackStackRecord.commitInternal(boolean allowStateLoss)
FragmentManagerImpl.enqueueAction(OpGenerator action, boolean allowStateLoss)
// 涉及到Handler的延时处理
FragmentManager.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);
}
}
}
handler将进一步操作Runnable
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
FragmentManager.execPendingActions()
FragmentManager.doPendingDeferredStart()
FragmentManager.startPendingDeferredFragments()
FragmentManager.performPendingDeferredStart(Fragment f)
FragmentManager.moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive){
case Fragment.ACTIVITY_CREATED:
onDestroyView();
mContainer.removeView(f.mView)
f.view.dispatchDetachedFromWindow();
f.mContainer = null;
f.mView = null;
case Fragment.CREATED:
f.performDestroy();
f.performDetach();
makeInactive(f);
f.mHost = null;
}
moveToState 是状态变化的核心方法,需要进一步查看源码
二、FragmentManager.moveToState解析
FragmentActivity维护着FragmentManager一个实例,而FragmentManager管理者Fragment的各个状态, 查看FragmentManagerImpl源码中
FragmentManagerImpl{
int mCurState = Fragment.INITIALIZING; //初始化状态
}
Fragment{
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
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.
}
mCurState就是当前FragmentManager的状态,mCurState只有一个方法中对其有赋值操作moveToState(int newState, boolean always)
而这个方法调用处如下:
public void dispatchCreate() {
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.CREATED);
}
public void dispatchActivityCreated() {
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.ACTIVITY_CREATED);
}
public void dispatchStart() {
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.STARTED);
}
public void dispatchResume() {
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.RESUMED);
}
public void dispatchPause() {
dispatchStateChange(Fragment.STARTED);
}
public void dispatchStop() {
mStopped = true;
dispatchStateChange(Fragment.STOPPED);
}
方法对应着状态值的调整,看命名好像和Activity的生命周期对于,我们再对照FragmentActivity的源码
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
public void dispatchActivityCreated() {
mHost.mFragmentManager.dispatchActivityCreated();
}
public void dispatchStart() {
mHost.mFragmentManager.dispatchStart();
}
public void dispatchResume() {
mHost.mFragmentManager.dispatchResume();
}
public void dispatchPause() {
mHost.mFragmentManager.dispatchPause();
}
public void dispatchStop() {
mHost.mFragmentManager.dispatchStop();
}
果然是由Activity来触发FragmentManager的状态变化 接下来详细看下FragmentManager.moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive)
方法 简化如下:
if (f.mState < newState) {
switch (f.mState) {
case Fragment.INITIALIZING:
//some code
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
//some code
}
case Fragment.ACTIVITY_CREATED:
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
//some code
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
//some code
}
}
} else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
//some code
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
//some code
}
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
//some code
}
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
//some code
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
//some code
}
}
}
f.mState = newState;
在每个case中都没有break,则会顺序执行,主要是fragment状态和FragmentManager的状态进行了对比,
- 1)fragment状态小于FragmentManager的状态,类似Activity已完成初始化,用户点击操作,开始addFragment,则开始顺序执行初始化Fragment的状态;
- 2)fragment状态大于FragmentManager的状态,类似Activity已完成初始化,用户点击操作,开始removeFragment,则开始删除Fragment 最终Fragment状态和FragmentManager的状态同步