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;
}
再来看parent!=null
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