前言
本章主要讲解下 Framgent 的核心原理;
基础用法
线上基础用法,其他的可以自行百度
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.contentlayout, "one", OneFragment);
transaction.commit();
// replace
// remove
// show
// hide
// addToBackStack
// setPrimaryNavigationFragment
生命周期
Fragment 的生命周期时序图;
Fragment 的生命周期时序管理是在 FragmentActivity 中进行的,我们来看下 Fragment 的生命周期是怎么和 Activity 进行绑定的;
我们从 onCreate 方法看起,可以看到这个 FragmentActivity 有很多关于 Framgent 分发的动作;
protected void onCreate(@Nullable Bundle savedInstanceState) {
// 省略部分代码
this.mFragments.dispatchCreate();
}
其他的生命周期方法中 也都会有类似的动作,我们随便找一个看下:
protected void onStart() {
super.onStart();
this.mFragments.dispatchStart();
}
而这个 mFraments 就是一个 FragmentController,它里面定义了一系列的 dispatch 逻辑
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
也就是 FragmentActivity 持有 FragmentController 间接持有了 FragmentHostCallback,通过这样的持有方式可以操作 Fragment 相关逻辑;
而所有的 dispatch 逻辑 最终都会走到 dispatchStateChange 方法,这个方法来分发一些 Fragment 身上的状态,总共是有下面这些状态
static final int INITIALIZING = -1; // Not yet attached.
static final int ATTACHED = 0; // Attached to the host.
static final int CREATED = 1; // Created.
static final int VIEW_CREATED = 2; // View Created.
static final int AWAITING_EXIT_EFFECTS = 3; // Downward state, awaiting exit effects
static final int ACTIVITY_CREATED = 4; // Fully created, not started.
static final int STARTED = 5; // Created and started, not resumed.
static final int AWAITING_ENTER_EFFECTS = 6; // Upward state, awaiting enter effects
static final int RESUMED = 7;
我们来探索下状态是怎么分发的,回到 dispatchStateChange 方法来;
private void dispatchStateChange(int nextState) {
try {
mExecutingActions = true;
mFragmentStore.dispatchStateChange(nextState);
moveToState(nextState, false);
if (USE_STATE_MANAGER) {
Set<SpecialEffectsController> controllers = collectAllSpecialEffectsController();
for (SpecialEffectsController controller : controllers) {
controller.forceCompleteAllOperations();
}
}
} finally {
mExecutingActions = false;
}
execPendingActions(true);
}
可以看到,不管什么状态进来,最终都是调用 moveToState 方法;
void moveToState(int newState, boolean always) {
if (this.mHost == null && newState != 0) {
throw new IllegalStateException("No activity");
} else if (always || newState != this.mCurState) {
// 赋值新传入进来的状态
this.mCurState = newState;
// 使用过的 Fragment 都会添加到 mAdded 中
int numAdded = this.mAdded.size();
Fragment f;
for(int i = 0; i < numAdded; ++i) {
f = (Fragment)this.mAdded.get(i);
// 移动 Framgent 到期望的状态
this.moveFragmentToExpectedState(f);
}
Iterator var6 = this.mActive.values().iterator();
while(true) {
do {
do {
if (!var6.hasNext()) {
this.startPendingDeferredFragments();
if (this.mNeedMenuInvalidate && this.mHost != null && this.mCurState == 4) {
this.mHost.onSupportInvalidateOptionsMenu();
this.mNeedMenuInvalidate = false;
}
return;
}
f = (Fragment)var6.next();
} while(f == null);
} while(!f.mRemoving && !f.mDetached);
if (!f.mIsNewlyAdded) {
this.moveFragmentToExpectedState(f);
}
}
}
}
我们进入这个 moveFragmentToExpectedState 方法看下:
void moveFragmentToExpectedState(Fragment f) {
if (f != null) {
if (!this.mActive.containsKey(f.mWho)) {
if (DEBUG) {
Log.v("FragmentManager", "Ignoring moving " + f + " to state " + this.mCurState + "since it is not added to " + this);
}
} else {
int nextState = this.mCurState;
if (f.mRemoving) {
if (f.isInBackStack()) {
nextState = Math.min(nextState, 1);
} else {
nextState = Math.min(nextState, 0);
}
}
this.moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
if (f.mView != null) {
Fragment underFragment = this.findFragmentUnder(f);
if (underFragment != null) {
View underView = underFragment.mView;
ViewGroup container = f.mContainer;
int underIndex = container.indexOfChild(underView);
int viewIndex = container.indexOfChild(f.mView);
if (viewIndex < underIndex) {
container.removeViewAt(viewIndex);
container.addView(f.mView, underIndex);
}
}
if (f.mIsNewlyAdded && f.mContainer != null) {
if (f.mPostponedAlpha > 0.0F) {
f.mView.setAlpha(f.mPostponedAlpha);
}
f.mPostponedAlpha = 0.0F;
f.mIsNewlyAdded = false;
AnimationOrAnimator anim = this.loadAnimation(f, f.getNextTransition(), true, f.getNextTransitionStyle());
if (anim != null) {
if (anim.animation != null) {
f.mView.startAnimation(anim.animation);
} else {
anim.animator.setTarget(f.mView);
anim.animator.start();
}
}
}
}
if (f.mHiddenChanged) {
this.completeShowHideFragment(f);
}
}
}
}
这个方法也调度到了 moveToState 方法,我们来分析这个方法,这个方法比较长,我们一点一点来看
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
switch (f.mState) {
case 0:
this.dispatchOnFragmentPreAttached(f, this.mHost.getContext(), false);
// 执行到这里,就会分发 Framgent 的 onAttach 方法
f.performAttach();
this.dispatchOnFragmentAttached(f, this.mHost.getContext(), false);
// 如果没有创建,执行 create
if (!f.mIsCreated) {
this.dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
f.performCreate(f.mSavedFragmentState);
this.dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = 1;
}
}
}
performAttach 方法:
void performAttach() {
for (OnPreAttachedListener listener: mOnPreAttachedListeners) {
listener.onPreAttached();
}
mOnPreAttachedListeners.clear();
mChildFragmentManager.attachController(mHost, createFragmentContainer(), this);
mState = ATTACHED;
mCalled = false;
// 回调 Fragment 的 onAttach 方法
onAttach(mHost.getContext());
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onAttach()");
}
mFragmentManager.dispatchOnAttachFragment(this);
mChildFragmentManager.dispatchAttach();
}
同理 performCreate 方法
void performCreate(Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
// 同时更新状态,是为了让下一个状态能流转起来;
mState = CREATED;
mCalled = false;
if (Build.VERSION.SDK_INT >= 19) {
mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_STOP) {
if (mView != null) {
mView.cancelPendingInputEvents();
}
}
}
});
}
mSavedStateRegistryController.performRestore(savedInstanceState);
// 回调 Fragment 的 onCreate 方法
onCreate(savedInstanceState);
mIsCreated = true;
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onCreate()");
}
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
所有的 performXXX 方法都执行两个核心操作,一个是更新状态,是为了让下一个状态能流转起来,另一个就是回调对应的 Fragment 的 XXX 方法;
因为源码中的这个 switch 中的每一个 case 都没有 break 关键字,可以一直流转下去;
所以,无论 Fragment 是从 onAttach 到 onResume 之间的任意一个方法进来,最终都会流转到 onResume 方法;
我们接着往下看 onCreateView 逻辑
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
switch (f.mState) {
case 1:
f.mContainer = container;
// 创建 View
f.performCreateView(f.performGetLayoutInflater(f.mSavedFragmentState), container, f.mSavedFragmentState);
// 分发 ActivityCreated
f.performActivityCreated(f.mSavedFragmentState);
this.dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
}
}
创建 View 的过程,还是调用的 inflater 的逻辑,创建 View 之后,分发 ActivityCreated 状态
就这样一直分发下去,直到 RESUME 的状态,RESUME 之后的生命周期变化就进入了 else 的逻辑;
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
if (f.mState <= newState) {
// onAttach -> onResume
} else if(f.mState > newState) {
// onResume -> onDestroy
}
}
我们来看下 else 的逻辑,执行到这里的时候,说明 Fragment 要退后台或者销毁了;整体的流转是和上面一样,从 resume -> pause -> stop -> destroyView -> destroy 这样的一个逻辑;
所以 Fragment 的生命周期分发就是这样实现的;
FragmentManager
getSupportFragmentManager() 最终拿到的是具体实现 FragmentManagerImpl;
FragmentTransaction
FragmentTransaction 的唯一实现就是 BackStackRecord;
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
add
public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment,
@Nullable String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
这个 OP_ADD 就是操作 Fragment 的标识
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;
void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
// 省略部分代码
// 创建一个 Op 对象,将 标识 和当前 Fragment 存起来了
addOp(new Op(opcmd, fragment));
}
创建一个 Op 对象,将 标识 和当前 Fragment 存起来了,然后存入到一个 mOps 的集合中;
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
commit
同理,其他命令也都是同样的操作;添加之后的统一处理,都在 commit 中,我们进入这个 commit 方法看下:
commit 有四个实现 commit,commitAllowingStateLoss,commitNow,commitNowAllowingStateLoss
@Override
public int commit() {
return commitInternal(false);
}
@Override
public int commitAllowingStateLoss() {
return commitInternal(true);
}
@Override
public void commitNow() {
disallowAddToBackStack();
mManager.execSingleAction(this, false);
}
@Override
public void commitNowAllowingStateLoss() {
disallowAddToBackStack();
mManager.execSingleAction(this, true);
}
我们可以看到 commit 和 commitAllowingStateLoss 都是调用的 commitInternal 只是传递的值不一样,这里 true 表示可以允许状态丢失,false 不允许状态丢失,我们进入这个 commitInternal 方法看下:
int commitInternal(boolean allowStateLoss) {
if (this.mCommitted) {
throw new IllegalStateException("commit already called");
} else {
if (FragmentManager.isLoggingEnabled(2)) {
Log.v("FragmentManager", "Commit: " + this);
LogWriter logw = new LogWriter("FragmentManager");
PrintWriter pw = new PrintWriter(logw);
this.dump(" ", pw);
pw.close();
}
this.mCommitted = true;
if (this.mAddToBackStack) {
this.mIndex = this.mManager.allocBackStackIndex();
} else {
this.mIndex = -1;
}
// 这里要重点关注,将事务放入一个队列中
this.mManager.enqueueAction(this, allowStateLoss);
return this.mIndex;
}
}
enqueueAction 将当前事务放到一个队列中;
void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
if (this.mHost == null) {
if (this.mDestroyed) {
throw new IllegalStateException("FragmentManager has been destroyed");
}
throw new IllegalStateException("FragmentManager has not been attached to a host.");
}
this.checkStateLoss();
}
synchronized(this.mPendingActions) {
if (this.mHost == null) {
if (!allowStateLoss) {
throw new IllegalStateException("Activity has been destroyed");
}
} else {
// 将当前事务放到了一个集合中,用来存放事务的集合
this.mPendingActions.add(action);
this.scheduleCommit();
}
}
}
mPendingActions.add(action) 将当前事务放到了一个集合中,用来存放事务的集合,然后调用 scheduleCommit 进行提交;
void scheduleCommit() {
synchronized(this.mPendingActions) {
boolean postponeReady = this.mPostponedTransactions != null && !this.mPostponedTransactions.isEmpty();
boolean pendingReady = this.mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
this.mHost.getHandler().removeCallbacks(this.mExecCommit);
// 通过 handler 执行
this.mHost.getHandler().post(this.mExecCommit);
this.updateOnBackPressedCallbackEnabled();
}
}
}
this.mHost.getHandler().post(this.mExecCommit) 通过 handler 执行这个命令
private Runnable mExecCommit = new Runnable() {
public void run() {
FragmentManager.this.execPendingActions(true);
}
};
最终调度到 execPendingActions 这个方法中;也就是事务的执行是在主线程执行的;
boolean execPendingActions(boolean allowStateLoss) {
this.ensureExecReady(allowStateLoss);
boolean didSomething;
// 重点关注的地方
for(didSomething = false; this.generateOpsForPendingActions(this.mTmpRecords, this.mTmpIsPop); didSomething = true) {
this.mExecutingActions = true;
try {
this.removeRedundantOperationsAndExecute(this.mTmpRecords, this.mTmpIsPop);
} finally {
this.cleanupExec();
}
}
this.updateOnBackPressedCallbackEnabled();
this.doPendingDeferredStart();
this.mFragmentStore.burpActive();
return didSomething;
}
generateOpsForPendingActions 生成操作为事务集合;
private boolean generateOpsForPendingActions(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isPop) {
boolean didSomething = false;
synchronized(this.mPendingActions) {
if (this.mPendingActions.isEmpty()) {
return false;
} else {
int numActions = this.mPendingActions.size();
for(int i = 0; i < numActions; ++i) {
// 取出事务集合中的每一项,然后调用 generateOps 方法;
didSomething |= ((OpGenerator)this.mPendingActions.get(i)).generateOps(records, isPop);
}
this.mPendingActions.clear();
this.mHost.getHandler().removeCallbacks(this.mExecCommit);
return didSomething;
}
}
}
取出事务集合中的每一项,然后调用 generateOps 方法,这个方法主要是将集合中的数据挪到了另一个集合中,并附带了一个标记;
public boolean generateOps(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop) {
if (FragmentManager.isLoggingEnabled(2)) {
Log.v("FragmentManager", "Run: " + this);
}
records.add(this);
isRecordPop.add(false);
if (this.mAddToBackStack) {
this.mManager.addBackStackState(this);
}
return true;
}
这个标记就是标记哪些事务是添加到了回退栈中,true 也就是调用了 addToBackStack,false 没有;也就是有栈操作和无栈操作是分两个集合运行的;
事务分完之后,执行 removeRedundantOperationsAndExecute 删除裁剪操作之后并执行
private void removeRedundantOperationsAndExecute(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop) {
if (!records.isEmpty()) {
if (records.size() != isRecordPop.size()) {
throw new IllegalStateException("Internal error with the back stack records");
} else {
this.executePostponedTransaction(records, isRecordPop);
int numRecords = records.size();
int startIndex = 0;
for(int recordNum = 0; recordNum < numRecords; ++recordNum) {
boolean canReorder = ((BackStackRecord)records.get(recordNum)).mReorderingAllowed;
if (!canReorder) {
if (startIndex != recordNum) {
// 执行关联操作,是一个优化逻辑,例如 add->remove->add 这样的话前面两步就是多余操作,可以移除掉
this.executeOpsTogether(records, isRecordPop, startIndex, recordNum);
}
int reorderingEnd = recordNum + 1;
if ((Boolean)isRecordPop.get(recordNum)) {
while(reorderingEnd < numRecords && (Boolean)isRecordPop.get(reorderingEnd) && !((BackStackRecord)records.get(reorderingEnd)).mReorderingAllowed) {
++reorderingEnd;
}
}
this.executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
startIndex = reorderingEnd;
recordNum = reorderingEnd - 1;
}
}
if (startIndex != numRecords) {
this.executeOpsTogether(records, isRecordPop, startIndex, numRecords);
}
}
}
}
executeOpsTogether 执行关联操作,是一个优化逻辑,例如 add->remove->add 这样的话前面两步就是多余操作,可以移除掉
private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
boolean allowReordering = ((BackStackRecord)records.get(startIndex)).mReorderingAllowed;
boolean addToBackStack = false;
if (this.mTmpAddedFragments == null) {
this.mTmpAddedFragments = new ArrayList();
} else {
this.mTmpAddedFragments.clear();
}
this.mTmpAddedFragments.addAll(this.mFragmentStore.getFragments());
Fragment oldPrimaryNav = this.getPrimaryNavigationFragment();
int postponeIndex;
for(postponeIndex = startIndex; postponeIndex < endIndex; ++postponeIndex) {
BackStackRecord record = (BackStackRecord)records.get(postponeIndex);
boolean isPop = (Boolean)isRecordPop.get(postponeIndex);
// 这里执行的就是移除操作
if (!isPop) {
oldPrimaryNav = record.expandOps(this.mTmpAddedFragments, oldPrimaryNav);
} else {
oldPrimaryNav = record.trackAddedFragmentsInPop(this.mTmpAddedFragments, oldPrimaryNav);
}
addToBackStack = addToBackStack || record.mAddToBackStack;
}
this.mTmpAddedFragments.clear();
if (!allowReordering) {
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex, false, this.mFragmentTransitionCallback);
}
// 前面逻辑走完之后,执行到这里
executeOps(records, isRecordPop, startIndex, endIndex);
postponeIndex = endIndex;
if (allowReordering) {
ArraySet<Fragment> addedFragments = new ArraySet();
this.addAddedFragments(addedFragments);
postponeIndex = this.postponePostponableTransactions(records, isRecordPop, startIndex, endIndex, addedFragments);
this.makeRemovedFragmentsInvisible(addedFragments);
}
if (postponeIndex != startIndex && allowReordering) {
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, postponeIndex, true, this.mFragmentTransitionCallback);
this.moveToState(this.mCurState, true);
}
for(int recordNum = startIndex; recordNum < endIndex; ++recordNum) {
BackStackRecord record = (BackStackRecord)records.get(recordNum);
boolean isPop = (Boolean)isRecordPop.get(recordNum);
if (isPop && record.mIndex >= 0) {
record.mIndex = -1;
}
record.runOnCommitRunnables();
}
if (addToBackStack) {
this.reportBackStackChanged();
}
}
executeOps 执行 Fragment 的操作
private static void executeOps(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
for(int i = startIndex; i < endIndex; ++i) {
BackStackRecord record = (BackStackRecord)records.get(i);
boolean isPop = (Boolean)isRecordPop.get(i);
if (isPop) {
// 有栈
record.bumpBackStackNesting(-1);
boolean moveToState = i == endIndex - 1;
record.executePopOps(moveToState);
} else {
// 无栈
record.bumpBackStackNesting(1);
record.executeOps();
}
}
}
这里也是分为两种,一种是有栈的,一种是无栈的,分开处理;我们来看下无栈的;
void executeOps() {
int numOps = this.mOps.size();
for(int opNum = 0; opNum < numOps; ++opNum) {
FragmentTransaction.Op op = (FragmentTransaction.Op)this.mOps.get(opNum);
Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(this.mTransition);
}
switch (op.mCmd) {
case 1:
f.setNextAnim(op.mEnterAnim);
this.mManager.setExitAnimationOrder(f, false);
// 执行 Framgent 的添加,添加之后就会走 Framgent 的生命周期
this.mManager.addFragment(f);
break;
case 2:
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
case 3:
f.setNextAnim(op.mExitAnim);
this.mManager.removeFragment(f);
break;
case 4:
f.setNextAnim(op.mExitAnim);
this.mManager.hideFragment(f);
break;
case 5:
f.setNextAnim(op.mEnterAnim);
this.mManager.setExitAnimationOrder(f, false);
this.mManager.showFragment(f);
break;
case 6:
f.setNextAnim(op.mExitAnim);
this.mManager.detachFragment(f);
break;
case 7:
f.setNextAnim(op.mEnterAnim);
this.mManager.setExitAnimationOrder(f, false);
this.mManager.attachFragment(f);
break;
case 8:
this.mManager.setPrimaryNavigationFragment(f);
break;
case 9:
this.mManager.setPrimaryNavigationFragment((Fragment)null);
break;
case 10:
this.mManager.setMaxLifecycle(f, op.mCurrentMaxState);
}
if (!this.mReorderingAllowed && op.mCmd != 1 && f != null) {
this.mManager.moveFragmentToExpectedState(f);
}
}
if (!this.mReorderingAllowed) {
this.mManager.moveToState(this.mManager.mCurState, true);
}
}
this.mManager.addFragment(f) 执行 Framgent 的添加,添加之后通过 moveToState 就会执行对应的生命周期
moveToState -> moveFragmentToExpectedState -> moveToState 就会到我们前面看到的Fragment生命周期的 moveToState 来分发对应的生命周期
void moveToState(@NonNull Fragment f, int newState) {
FragmentStateManager fragmentStateManager = this.mFragmentStore.getFragmentStateManager(f.mWho);
if (fragmentStateManager == null) {
fragmentStateManager = new FragmentStateManager(this.mLifecycleCallbacksDispatcher, f);
fragmentStateManager.setFragmentManagerState(1);
}
newState = Math.min(newState, fragmentStateManager.computeMaxState());
if (f.mState <= newState) {
if (f.mState < newState && !this.mExitAnimationCancellationSignals.isEmpty()) {
this.cancelExitAnimation(f);
}
switch (f.mState) {
case -1:
if (newState > -1) {
if (isLoggingEnabled(3)) {
Log.d("FragmentManager", "moveto ATTACHED: " + f);
}
if (f.mTarget != null) {
if (!f.mTarget.equals(this.findActiveFragment(f.mTarget.mWho))) {
throw new IllegalStateException("Fragment " + f + " declared target fragment " + f.mTarget + " that does not belong to this FragmentManager!");
}
if (f.mTarget.mState < 1) {
this.moveToState(f.mTarget, 1);
}
f.mTargetWho = f.mTarget.mWho;
f.mTarget = null;
}
if (f.mTargetWho != null) {
Fragment target = this.findActiveFragment(f.mTargetWho);
if (target == null) {
throw new IllegalStateException("Fragment " + f + " declared target fragment " + f.mTargetWho + " that does not belong to this FragmentManager!");
}
if (target.mState < 1) {
this.moveToState(target, 1);
}
}
fragmentStateManager.attach(this.mHost, this, this.mParent);
}
case 0:
if (newState > 0) {
fragmentStateManager.create();
}
case 1:
if (newState > -1) {
fragmentStateManager.ensureInflatedView();
}
if (newState > 1) {
fragmentStateManager.createView(this.mContainer);
fragmentStateManager.activityCreated();
fragmentStateManager.restoreViewState();
}
case 2:
if (newState > 2) {
fragmentStateManager.start();
}
case 3:
if (newState > 3) {
fragmentStateManager.resume();
}
}
} else if (f.mState > newState) {
switch (f.mState) {
case 4:
if (newState < 4) {
fragmentStateManager.pause();
}
case 3:
if (newState < 3) {
fragmentStateManager.stop();
}
case 2:
if (newState < 2) {
if (isLoggingEnabled(3)) {
Log.d("FragmentManager", "movefrom ACTIVITY_CREATED: " + f);
}
if (f.mView != null && this.mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
fragmentStateManager.saveViewState();
}
FragmentAnim.AnimationOrAnimator anim = null;
if (f.mView != null && f.mContainer != null) {
f.mContainer.endViewTransition(f.mView);
f.mView.clearAnimation();
if (!f.isRemovingParent()) {
if (this.mCurState > -1 && !this.mDestroyed && f.mView.getVisibility() == 0 && f.mPostponedAlpha >= 0.0F) {
anim = FragmentAnim.loadAnimation(this.mHost.getContext(), this.mContainer, f, false);
}
f.mPostponedAlpha = 0.0F;
ViewGroup container = f.mContainer;
View view = f.mView;
if (anim != null) {
f.setStateAfterAnimating(newState);
FragmentAnim.animateRemoveFragment(f, anim, this.mFragmentTransitionCallback);
}
container.removeView(view);
if (container != f.mContainer) {
return;
}
}
}
if (this.mExitAnimationCancellationSignals.get(f) == null) {
this.destroyFragmentView(f);
} else {
f.setStateAfterAnimating(newState);
}
}
case 1:
if (newState < 1) {
boolean beingRemoved = f.mRemoving && !f.isInBackStack();
if (!beingRemoved && !this.mNonConfig.shouldDestroy(f)) {
if (f.mTargetWho != null) {
Fragment target = this.findActiveFragment(f.mTargetWho);
if (target != null && target.getRetainInstance()) {
f.mTarget = target;
}
}
} else {
this.makeInactive(fragmentStateManager);
}
if (this.mExitAnimationCancellationSignals.get(f) != null) {
f.setStateAfterAnimating(newState);
newState = 1;
} else {
fragmentStateManager.destroy(this.mHost, this.mNonConfig);
}
}
case 0:
if (newState < 0) {
fragmentStateManager.detach(this.mNonConfig);
}
}
}
if (f.mState != newState) {
if (isLoggingEnabled(3)) {
Log.d("FragmentManager", "moveToState: Fragment state for " + f + " not updated inline; expected state " + newState + " found " + f.mState);
}
f.mState = newState;
}
}
addBackToStack
我们接下来看下 回退栈 addBackToStack
public FragmentTransaction addToBackStack(@Nullable String name) {
if (!this.mAllowAddToBackStack) {
throw new IllegalStateException("This FragmentTransaction is not allowed to be added to the back stack.");
} else {
this.mAddToBackStack = true;
this.mName = name;
return this;
}
}
这里仅仅是把 mAddToBackStack 设置为 true,那么这个标志位在哪里使用的呢?就在前面我们说 commit 的时候;
if (this.mAddToBackStack) {
this.mIndex = this.mManager.allocBackStackIndex();
}
allocBackStackIndex 这个方法我们来看下:
public int allocBackStackIndex(BackStackRecord bse) {
synchronized(this) {
int index;
if (this.mAvailBackStackIndices != null && this.mAvailBackStackIndices.size() > 0) {
index = (Integer)this.mAvailBackStackIndices.remove(this.mAvailBackStackIndices.size() - 1);
if (DEBUG) {
Log.v("FragmentManager", "Adding back stack index " + index + " with " + bse);
}
this.mBackStackIndices.set(index, bse);
return index;
} else {
if (this.mBackStackIndices == null) {
this.mBackStackIndices = new ArrayList();
}
// 如果是第一次,这里获取到的是 0
index = this.mBackStackIndices.size();
if (DEBUG) {
Log.v("FragmentManager", "Setting back stack index " + index + " to " + bse);
}
// 将事务添加到这个集合中,并返回对应的 index;
this.mBackStackIndices.add(bse);
return index;
}
}
}
这里有一点比较饶,就是 this.mAvailBackStackIndices != null 这看起来好像一直不成立似的,就会导致一直都是走 else 逻辑进行添加,其实并不是,我们往下看有一个 freeBackStackSize 的逻辑;
public void freeBackStackIndex(int index) {
synchronized(this) {
// 先把对应索引的值设置为 null
this.mBackStackIndices.set(index, (Object)null);
if (this.mAvailBackStackIndices == null) {
this.mAvailBackStackIndices = new ArrayList();
}
if (DEBUG) {
Log.v("FragmentManager", "Freeing back stack index " + index);
}
// 把索引存入这个集合中
this.mAvailBackStackIndices.add(index);
}
}
当我们要释放某个索引的时候,就会先把对应索引的值设置为 null 然后将对应的索引添加到 mAvailBackStackIndices 这个集合中,当我们下次添加的时候,此时 this.mAvailBackStackIndices != null 就会成立,就能进入对应的逻辑中
// 获取集合中最后一项的值,也就是存入的第一个索引值
index = (Integer)this.mAvailBackStackIndices.remove(this.mAvailBackStackIndices.size() - 1);
this.mBackStackIndices.set(index, bse);
获取对应的索引,并更新对应索引的值为对应的事务;回退栈逻辑就到这里了,我们接下来看下状态的保存和恢复。
onSaveInstanceState
通过 onSaveInstanceState 方法最终会调用到 FragmentController 的 saveAllState 方法
public Parcelable saveAllState() {
return mHost.mFragmentManager.saveAllState();
}
我们进入这个 saveAllState 方法看下:
Parcelable saveAllState() {
this.forcePostponedTransactions();
this.endAnimatingAwayFragments();
this.execPendingActions();
this.mStateSaved = true;
if (this.mActive.isEmpty()) {
return null;
} else {
int size = this.mActive.size();
ArrayList<FragmentState> active = new ArrayList(size);
boolean haveFragments = false;
Iterator var4 = this.mActive.values().iterator();
while(true) {
Fragment f;
Fragment target;
do {
if (!var4.hasNext()) {
if (!haveFragments) {
if (DEBUG) {
Log.v("FragmentManager", "saveAllState: no fragments!");
}
return null;
}
ArrayList<String> added = null;
BackStackState[] backStack = null;
size = this.mAdded.size();
if (size > 0) {
added = new ArrayList(size);
Iterator var10 = this.mAdded.iterator();
while(var10.hasNext()) {
target = (Fragment)var10.next();
added.add(target.mWho);
if (target.mFragmentManager != this) {
this.throwException(new IllegalStateException("Failure saving state: active " + target + " was removed from the FragmentManager"));
}
if (DEBUG) {
Log.v("FragmentManager", "saveAllState: adding fragment (" + target.mWho + "): " + target);
}
}
}
if (this.mBackStack != null) {
size = this.mBackStack.size();
if (size > 0) {
backStack = new BackStackState[size];
for(int i = 0; i < size; ++i) {
backStack[i] = new BackStackState((BackStackRecord)this.mBackStack.get(i));
if (DEBUG) {
Log.v("FragmentManager", "saveAllState: adding back stack #" + i + ": " + this.mBackStack.get(i));
}
}
}
}
FragmentManagerState fms = new FragmentManagerState();
fms.mActive = active;
fms.mAdded = added;
fms.mBackStack = backStack;
if (this.mPrimaryNav != null) {
fms.mPrimaryNavActiveWho = this.mPrimaryNav.mWho;
}
fms.mNextFragmentIndex = this.mNextFragmentIndex;
return fms;
}
f = (Fragment)var4.next();
} while(f == null);
if (f.mFragmentManager != this) {
this.throwException(new IllegalStateException("Failure saving state: active " + f + " was removed from the FragmentManager"));
}
haveFragments = true;
FragmentState fs = new FragmentState(f);
active.add(fs);
if (f.mState > 0 && fs.mSavedFragmentState == null) {
// 其他没什么值得关注的,重点是这里 saveFragmentBasicState
fs.mSavedFragmentState = this.saveFragmentBasicState(f);
if (f.mTargetWho != null) {
target = (Fragment)this.mActive.get(f.mTargetWho);
if (target == null) {
this.throwException(new IllegalStateException("Failure saving state: " + f + " has target not in fragment manager: " + f.mTargetWho));
}
if (fs.mSavedFragmentState == null) {
fs.mSavedFragmentState = new Bundle();
}
this.putFragment(fs.mSavedFragmentState, "android:target_state", target);
if (f.mTargetRequestCode != 0) {
fs.mSavedFragmentState.putInt("android:target_req_state", f.mTargetRequestCode);
}
}
} else {
fs.mSavedFragmentState = f.mSavedFragmentState;
}
if (DEBUG) {
Log.v("FragmentManager", "Saved state of " + f + ": " + fs.mSavedFragmentState);
}
}
}
}
整体就是添加状态,其他没什么值得关注的,重点是这里 saveFragmentBasicState,我们的 Framgent 会解析 View 树,这里会把这个 View 树保存下来,我们进入这个方法看下:
Bundle saveFragmentBasicState(Fragment f) {
Bundle result = null;
if (this.mStateBundle == null) {
this.mStateBundle = new Bundle();
}
f.performSaveInstanceState(this.mStateBundle);
this.dispatchOnFragmentSaveInstanceState(f, this.mStateBundle, false);
if (!this.mStateBundle.isEmpty()) {
result = this.mStateBundle;
this.mStateBundle = null;
}
if (f.mView != null) {
// 保存这个 View 的状态
this.saveFragmentViewState(f);
}
if (f.mSavedViewState != null) {
if (result == null) {
result = new Bundle();
}
result.putSparseParcelableArray("android:view_state", f.mSavedViewState);
}
if (!f.mUserVisibleHint) {
if (result == null) {
result = new Bundle();
}
result.putBoolean("android:user_visible_hint", f.mUserVisibleHint);
}
return result;
}
通过 saveFragmentViewState 来保存对应的 View 的状态;
void saveFragmentViewState(Fragment f) {
if (f.mInnerView != null) {
if (this.mStateArray == null) {
this.mStateArray = new SparseArray();
} else {
this.mStateArray.clear();
}
f.mInnerView.saveHierarchyState(this.mStateArray);
if (this.mStateArray.size() > 0) {
f.mSavedViewState = this.mStateArray;
this.mStateArray = null;
}
}
}
整体和 Activity 的状态保存很相似,最终也是存到了 Bundle 中,然后在界面重新创建的时候恢复
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreSaveState(p);
}
restoreSaveState 整体逻辑就是把存入的数据 再取出来,感兴趣的可以自行看下源码;
好了,Framgent 就讲到这里吧,感谢您的观看
下一章预告
MVC、MVP、MVVM
欢迎三连
来都来了,点个关注点个赞吧,你的支持是我最大的动力~