StateMachine

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值