当我们点击了返回键,首先收到消息的还是activity,如果回退栈有fragment,则有fragment manager处理, 否则调用finish():
//in class Activity/** * Called when the activity has detected the user's press of the back * key. The default implementation simply finishes the current activity, * but you can override this to do whatever you want. */ public void onBackPressed() { if (!mFragments.popBackStackImmediate()) { finish(); } }
在FragmentManager中(由FragmentManagerImp实现),首先将事务队列里尚未执行的事务执行完毕, 然后处理回退操作。实际使用的时候,时常可以看到这样的场景:点击一个按钮(会跳转到另一个fragment或activity)然后马上点击回退,可以感受到屏幕的闪烁, 在性能稍差的设备上尤其明显, 其实这些现象都可以在这里找到答案。
@Override public boolean popBackStackImmediate() { checkStateLoss(); executePendingTransactions(); return popBackStackState(mActivity.mHandler, null, -1, 0); }
这里操作的是事务记录,虽然感觉像是操作的fragment。弹出事务时, 可以是弹出一个,也可以根据条件弹出多个(可以认为控制mBackStack的容量),然后对栈顶的事务执行恢复显示:即调用改事务的 popFromBackStack(boolean doStateMove)方法。
boolean popBackStackState(Handler handler, 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; } final BackStackRecord bss = mBackStack.remove(last); bss.popFromBackStack(true); reportBackStackChanged(); } else { int index = -1; if (name != null || id >= 0) { // If a name or ID is specified, look for that place in // the stack. index = mBackStack.size()-1; while (index >= 0) { BackStackRecord bss = mBackStack.get(index); if (name != null && name.equals(bss.getName())) { break; } if (id >= 0 && id == bss.mIndex) { break; } index--; } if (index < 0) { return false; } if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) { index--; // Consume all following entries that match. while (index >= 0) { BackStackRecord bss = mBackStack.get(index); if ((name != null && name.equals(bss.getName())) || (id >= 0 && id == bss.mIndex)) { index--; continue; } break; } } } if (index == mBackStack.size()-1) { return false; } final ArrayListstates = new ArrayList (); for (int i=mBackStack.size()-1; i>index; i--) { states.add(mBackStack.remove(i)); } final int LAST = states.size()-1; for (int i=0; i<=LAST; i++) { if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i)); states.get(i).popFromBackStack(i == LAST); } reportBackStackChanged(); } return true; }
最后是BackStackRecord的 popFromBackStack方法, 和BackStackRecord的 run() 方法是相对应的, 最后还是要通过FragmentManager的 moveToState来执行实际的处理(激活fragment的生命周期方法)
public void popFromBackStack(boolean doStateMove) { if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "popFromBackStack: " + this); LogWriter logw = new LogWriter(TAG); PrintWriter pw = new PrintWriter(logw); dump(" ", null, pw, null); } bumpBackStackNesting(-1); Op op = mTail; while (op != null) { switch (op.cmd) { case OP_ADD: { Fragment f = op.fragment; f.mNextAnim = op.popExitAnim; mManager.removeFragment(f, FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle); } break; case OP_REPLACE: { Fragment f = op.fragment; if (f != null) { f.mNextAnim = op.popExitAnim; mManager.removeFragment(f, FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle); } if (op.removed != null) { for (int i=0; i= 0) { mManager.freeBackStackIndex(mIndex); mIndex = -1; } }