1
2
3
4
5
6
StateInfo
/** * Information about a state. * Used to maintain the hierarchy. */ private class StateInfo { /** The state */ //记录当前的状态 State state; /** The parent of this state, null if there is no parent */ //指向父节点,最终会是一个二叉树结构 StateInfo parentStateInfo; /** True when the state has been entered and on the stack */ //true代表当前状态处于激活状态,它的状态已经保存在stack中 boolean active; }
processMsg
private final void processMsg(Message msg) { //mStateStack记录了当前处于激活状态的所有状态,其中mStateStackTopIndex也就是数组最后一个是当前的状态 StateInfo curStateInfo = mStateStack[mStateStackTopIndex]; if (isQuit(msg)) { transitionTo(mQuittingState); } else { //某个状态的processMessage方法若返回true则表示这个消息它能够处理且已经处理完毕,返回false则表示它未将其处理或未处理完毕 while (!curStateInfo.state.processMessage(msg)) { //走到这里表示当前状态返回false,那么这里我们就指向当前状态的父状态,让它的processMessage方法来处理 curStateInfo = curStateInfo.parentStateInfo; if (curStateInfo == null) { //这意味着父状态为空,那么谁也不能处理这个消息了,只能交给StateMachine的unhandledMessage来做最后的处理 mSm.unhandledMessage(msg); break; } } //这个循环退出的条件是:当前状态或其某个父状态能够处理这个消息,或者没有任何一个父状态可以处理这个消息 } }
setupTempStateStackWithStatesToEnter
private final StateInfo setupTempStateStackWithStatesToEnter(State destState) { //mTempStateStack和mTempStateStackCount用来记录进入destState的路径 mTempStateStackCount = 0; //mStateInfo记录着所有的状态和对应的状态信息: //private HashMap<State, StateInfo> mStateInfo = new HashMap<State, StateInfo>(); StateInfo curStateInfo = mStateInfo.get(destState); do { mTempStateStack[mTempStateStackCount++] = curStateInfo; curStateInfo = curStateInfo.parentStateInfo; } while ((curStateInfo != null) && !curStateInfo.active); //退出循环的条件是:已经到了这个状态树的根状态了或者某个父状态已经是激活状态了 return curStateInfo; }
invokeExitMethods
//从当前状态不断向父状态退出,知道到达根据目标状态获取到的commonStateInfo,或者已经退出到了根状态 private final void invokeExitMethods(StateInfo commonStateInfo) { while ((mStateStackTopIndex >= 0) && (mStateStack[mStateStackTopIndex] != commonStateInfo)) { //mStateStackTopIndex指向当前的状态 State curState = mStateStack[mStateStackTopIndex].state; //调用当前状态的exit方法 curState.exit(); //exit后则设置当前状态的active为false mStateStack[mStateStackTopIndex].active = false; //mStateStackTopIndex索引减一 mStateStackTopIndex -= 1; } }
moveTempStateStackToStateStack
//mStateStack保存着目标父状态的所有父状态的信息 //mTempStateStack保存着从目标父状态到目标状态的路径,最顶层是目标父状态 private final int moveTempStateStackToStateStack() { int startingIndex = mStateStackTopIndex + 1; int i = mTempStateStackCount - 1; int j = startingIndex; while (i >= 0) { mStateStack[j] = mTempStateStack[i]; j += 1; i -= 1; } mStateStackTopIndex = j - 1; return startingIndex; }
invokeEnterMethods
private final void invokeEnterMethods(int stateStackEnteringIndex) { for (int i = stateStackEnteringIndex; i <= mStateStackTopIndex; i++) { mStateStack[i].state.enter(); mStateStack[i].active = true; } }
transitionTo
private final void transitionTo(IState destState) { //调用transitionTo方法时只是mDestState记录了目标状态,并没有真正的transition //在handleMessage执行到最后,会调用performTransitions来执行真正的transition mDestState = (State) destState; }
performTransitions
private void performTransitions() { State destState = null; //为何这里是个循环?难道mDestState还会被赋其它值? while (mDestState != null) { //保存mDestState destState = mDestState; mDestState = null; //找到当前状态与目标状态的公共父状态,并且mTempStateStack中记录着从目标状态到公共父状态的路径 StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState); //从当前状态到公共父状态,依次调用exit方法,并设置active为false invokeExitMethods(commonStateInfo); //将mTempStateStack中的记录从后至前复制到mStateStack中的公共父状态之后,相当与更新mStateStack,指向transite之后的新路径 int stateStackEnteringIndex = moveTempStateStackToStateStack(); //从公共父状态依次进入到目标状态 invokeEnterMethods(stateStackEnteringIndex); //不解…… moveDeferredMessageAtFrontOfQueue(); } //对目标状态为QuittingState和HaltingState的状态做些特殊处理 if (destState != null) { if (destState == mQuittingState) { mSm.onQuitting(); cleanupAfterQuitting(); } else if (destState == mHaltingState) { mSm.onHalting(); } } }
关于addState方法,我们先考虑简单的case:parent=null
private final StateInfo addState(State state, State parent) { //首先根据state去mStateInfo中查询是否已经有这个State StateInfo stateInfo = mStateInfo.get(state); if (stateInfo == null) { //此State不存在,那么需要创建一个新的StateInfo,并把它添加到mStateInfo中 stateInfo = new StateInfo(); mStateInfo.put(state, stateInfo); } //初始化新创建的StateInfo,并将其返回,很简单 stateInfo.state = state; stateInfo.parentStateInfo = parentStateInfo; stateInfo.active = false; return stateInfo; }
private final StateInfo addState(State state, State parent) { //这里需要保证父状态是存在的 StateInfo parentStateInfo = null; if (parent != null) { parentStateInfo = mStateInfo.get(parent); if (parentStateInfo == null) { //当父状态不存在时,则再创建一个级别树,父状态作为根状态 parentStateInfo = addState(parent, null); } } StateInfo stateInfo = mStateInfo.get(state); if (stateInfo == null) { stateInfo = new StateInfo(); mStateInfo.put(state, stateInfo); } //如果要添加的状态已经有父状态,而且跟当前指定的父状态不一致,表明是要把一个状态添加到不同的级别树中,这是不允许的 if ((stateInfo.parentStateInfo != null) && (stateInfo.parentStateInfo != parentStateInfo)) { throw new RuntimeException("state already added"); } stateInfo.state = state; stateInfo.parentStateInfo = parentStateInfo; stateInfo.active = false; if (mDbg) Log.d(TAG, "addStateInternal: X stateInfo: " + stateInfo); return stateInfo; }
7