分析例子

对StateMachine中例子进行逐步分析

其状态切换逻辑图如下:

        mP1      mP2       /   \      mS2   mS1 <-InitState

几条重要的概念:

  • 1 State方法有enter()/exit() 分别在进入和离开当前状态执行。
  • 2 需要重写State中processMessage来完成自己的状态切换逻辑。
  • 3 状态机初始化的时候,在根节点到初始节点上的节点都会执行enter。且执行顺序是从根节点开始。
  • 4 在进行状态切换的时候,是从目标节点向上查找跟当前的节点的共同父节点。如图:
     mP1     /  \    s1   s2   /  \ s3   s4  <- startstate  /s5  <- destate// 从目标节点 s5 向上查找,找到s1是和s4 时共同父节点。// 则从s4开始向上执行exit()方法。再从s3开始到s5 执行enter()方法。
  • 4 使用deferMessage会影响消息处理的顺序
class Hsm1 extends StateMachine {    public static final int CMD_1 = 1;    public static final int CMD_2 = 2;    public static final int CMD_3 = 3;    public static final int CMD_4 = 4;    public static final int CMD_5 = 5;    public static Hsm1 makeHsm1() {        log("makeHsm1 E");        Hsm1 sm = new Hsm1("hsm1");        sm.start();        log("makeHsm1 X");        return sm;    }    Hsm1(String name) {        super(name);        log("ctor E");        // Add states, use indentation to show hierarchy        addState(mP1);            addState(mS1, mP1);            addState(mS2, mP1);        addState(mP2);        // Set the initial state        setInitialState(mS1);        log("ctor X");    }    class P1 extends State {        @Override         public void enter() {            log("mP1.enter");        }        @Override        public boolean processMessage(Message message) {            boolean retVal;            log("mP1.processMessage what=" + message.what);            switch(message.what) {            case CMD_2:                // CMD_2 will arrive in mS2 before CMD_3                sendMessage(obtainMessage(CMD_3));                deferMessage(message);                transitionTo(mS2);                retVal = HANDLED;                break;            default:                // Any message we don't understand in this state invokes unhandledMessage                retVal = NOT_HANDLED;                break;            }            return retVal;        }        @Overrid        public void exit() {            log("mP1.exit");        }    }    class S1 extends State {              @Override         public void enter() {            log("mS1.enter");        }              @Override        public boolean processMessage(Message message) {            log("S1.processMessage what=" + message.what);            if (message.what == CMD_1) {                // Transition to ourself to show that enter/exit is called                transitionTo(mS1);                return HANDLED;            } else {                // Let parent process all other messages                return NOT_HANDLED;            }        }        @Override         public void exit() {            log("mS1.exit");        }    }    class S2 extends State {        @Override         public void enter() {            log("mS2.enter");        }               @Override        public boolean processMessage(Message message) {            boolean retVal;            log("mS2.processMessage what=" + message.what);            switch(message.what) {            case(CMD_2):                sendMessage(obtainMessage(CMD_4));                retVal = HANDLED;                break;            case(CMD_3):                deferMessage(message);                transitionTo(mP2);                retVal = HANDLED;                break;            default:                retVal = NOT_HANDLED;                break;            }            return retVal;        }                @Override         public void exit() {            log("mS2.exit");        }    }    class P2 extends State {        @Override         public void enter() {            log("mP2.enter");            sendMessage(obtainMessage(CMD_5));        }        @Override         public boolean processMessage(Message message) {            log("P2.processMessage what=" + message.what);            switch(message.what) {            case(CMD_3):                break;            case(CMD_4):                break;            case(CMD_5):                transitionToHaltingState();                break;            }            return HANDLED;        }        @Override         public void exit() {            log("mP2.exit");        }    }    @Override    void onHalting() {        log("halting");        synchronized (this) {            this.notifyAll();        }    }    P1 mP1 = new P1();    S1 mS1 = new S1();    S2 mS2 = new S2();    P2 mP2 = new P2();}

分析源码

想要使用状态机分三步,

初始化流程

1 继承StateMachine。2 添加状态。3 启动状态机。

class Hsm1 extends StateMachine {    public static Hsm1 makeHsm1() {        log("makeHsm1 E");        Hsm1 sm = new Hsm1("hsm1");        sm.start();        log("makeHsm1 X");        return sm;    }    Hsm1(String name) {        super(name);        log("ctor E");        // Add states, use indentation to show hierarchy        addState(mP1);            addState(mS1, mP1);            addState(mS2, mP1);        addState(mP2);        // Set the initial state        setInitialState(mS1);        log("ctor X");    }   ...}
  • 1 添加状态
    public final void addState(State state) {        mSmHandler.addState(state, null);    }        private final StateInfo addState(State state, State parent) {            ...            StateInfo parentStateInfo = null;            if (parent != null) {                parentStateInfo = mStateInfo.get(parent);                if (parentStateInfo == null) {                    // Recursively add our parent as it's not been added yet.                    parentStateInfo = addState(parent, null);                }            }            StateInfo stateInfo = mStateInfo.get(state);            if (stateInfo == null) {                stateInfo = new StateInfo();                mStateInfo.put(state, stateInfo);            }            ...            stateInfo.state = state;            stateInfo.parentStateInfo = parentStateInfo;            stateInfo.active = false;            if (mDbg) mSm.log("addStateInternal: X stateInfo: " + stateInfo);            return stateInfo;        }

添加节点的时候,需要同时传入父节点。当没有父节点的时候,不执行递推查询。生成StateInfo和State进行映射。其实StateInfo就是一个链表。parentStateInfo是指向父节点的,active表明当前的节点是否被激活。

结合调用段的代码进行分析,

        //没有传入父节点,则mP1就是根节点,并将其加入mStateInfo Map中并进行映射        //其StateInfo中的parentStateInfo为null,当前的节点并灭有被激活。        addState(mP1);        //传入mP1作为父节点,则从mStateInfo中取出的mP1的StateInfo        //mStateInfo没有mS1的StateInfo信息,初始其StateInfo将其加入mStateInfo        //其StateInfo中的parentStateInfo指向mP1,当前节点没有被激活        addState(mS1, mP1);                //同mS1 添加的分析步骤          addState(mS2, mP1);                //同mP1 添加的分析步骤        addState(mP2);                //设置初始化的节点指向mS1,其后的代码就是简单的赋值        setInitialState(mS1);

再所有的State添加完毕后,就需要启动状态机

    public static Hsm1 makeHsm1() {        log("makeHsm1 E");        Hsm1 sm = new Hsm1("hsm1");        sm.start();        log("makeHsm1 X");        return sm;    }        //StateMachine.java        private final void completeConstruction() {            if (mDbg) mSm.log("completeConstruction: E");            /**             * Determine the maximum depth of the state hierarchy             * so we can allocate the state stacks.             */                          //查找最深的那个分支。换句话理解就是测量这颗树一共有多少度。             //然后会根据maxDepth 创建数组。做成类似于栈结构            int maxDepth = 0;            for (StateInfo si : mStateInfo.values()) {                int depth = 0;                for (StateInfo i = si; i != null; depth++) {                    i = i.parentStateInfo;                }                if (maxDepth < depth) {                    maxDepth = depth;                }            }            if (mDbg) mSm.log("completeConstruction: maxDepth=" + maxDepth);            //根据maxDepth创建数组,是保证能装下从根节点到子节点中所有的路径            mStateStack = new StateInfo[maxDepth];            mTempStateStack = new StateInfo[maxDepth];                        //初始化State,做两步。1 从初始节点向上找到根节点。并将其放置在mTempStateStack            //2 将mTempStateStack倒序拷贝到mStateStack            setupInitialStateStack();            /** Sending SM_INIT_CMD message to invoke enter methods asynchronously */            sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));            if (mDbg) mSm.log("completeConstruction: X");        }                //--- from completeConstruction()        private final void setupInitialStateStack() {            if (mDbg) {                mSm.log("setupInitialStateStack: E mInitialState=" + mInitialState.getName());            }                        //拿到初始节点,(StateInfo是一个指向根节点的单向链表, curStateInfo就像是一个指针)            StateInfo curStateInfo = mStateInfo.get(mInitialState);                      //当前的链表指向初始节点,然后向上一直到根节点。             //(mS1->mP1)因为根节点的parenStateInfo是null。           // mS1 curStateInfo != null mTempStateStackCount = 0;           // mP1 curStateInfo.parentStateInfo != null mTempStateStackCount = 1;           // null mP1.parentStateInfo == null mTempStateStackCount = 2;            for (mTempStateStackCount = 0; curStateInfo != null; mTempStateStackCount++) {                mTempStateStack[mTempStateStackCount] = curStateInfo;                curStateInfo = curStateInfo.parentStateInfo;            }            // Empty the StateStack            //记住此处将mStateStackTopIndex赋值为-1,因为后续的改变State也会用到此state            mStateStackTopIndex = -1;                        //当前的mTempStateStack的顺序是 [mS1, mP1] 我们希望拿到顺序是[mP1, mS1]            moveTempStateStackToStateStack();        }        //---  from setupInitialStateStack()        private final int moveTempStateStackToStateStack() {            // startingIndex为0            int startingIndex = mStateStackTopIndex + 1;            // mTempStateStackCount = 2, i = 1;            int i = mTempStateStackCount - 1;            // j = 0;            int j = startingIndex;            while (i >= 0) {  // i=1  ===>  i=0  ===>  i=-1(terminal)                if (mDbg) mSm.log("moveTempStackToStateStack: i=" + i + ",j=" + j);                mStateStack[j] = mTempStateStack[i];                j += 1;                i -= 1;            }                        // j = 2, mStateStackTopIndex = 1;            mStateStackTopIndex = j - 1;            if (mDbg) {                mSm.log("moveTempStackToStateStack: X mStateStackTop=" + mStateStackTopIndex                        + ",startingIndex=" + startingIndex + ",Top="                        + mStateStack[mStateStackTopIndex].state.getName());            }                        //起始还是为0            //为什么要返回这个了?是为了后面的在改变状态的是,从共同节点作为起点。            return startingIndex;        }        //--- from sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));        // mSmHandlerObj是为了区分是状态机内部的消息,不是由外部进行驱动的。        // 且状态机的启动只能由内部启动        @Override        public final void handleMessage(Message msg) {            if (!mHasQuit) {                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {                    mSm.onPreHandleMessage(msg);                }                if (mDbg) mSm.log("handleMessage: E msg.what=" + msg.what);                /** Save the current message */                mMsg = msg;                /** State that processed the message */                State msgProcessedState = null;                if (mIsConstructionCompleted || (mMsg.what == SM_QUIT_CMD)) {                    /** Normal path */                    msgProcessedState = processMsg(msg);                } else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD)                        && (mMsg.obj == mSmHandlerObj)) {                    /** Initial one time path. */                    mIsConstructionCompleted = true;                    invokeEnterMethods(0);                } else {                    throw new RuntimeException("StateMachine.handleMessage: "                            + "The start method not called, received msg: " + msg);                }                performTransitions(msgProcessedState, msg);                // We need to check if mSm == null here as we could be quitting.                if (mDbg && mSm != null) mSm.log("handleMessage: X");                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {                    mSm.onPostHandleMessage(msg);                }            }        }        //--- from  handleMessage()       private final void invokeEnterMethods(int stateStackEnteringIndex) {            //此处mStateStackTopIndex = 1. 是在moveTempStateStackToStateStack方法中算出来的。            //stateStackEnteringIndex = 0; 此处就是从根节点向下进行初始化  [mP1, mS1]            //在调用state的enter()方法, 并将mStateInfo.active 置为 true            for (int i = stateStackEnteringIndex; i <= mStateStackTopIndex; i++) {                if (stateStackEnteringIndex == mStateStackTopIndex) {                    // Last enter state for transition                    mTransitionInProgress = false;                }                if (mDbg) mSm.log("invokeEnterMethods: " + mStateStack[i].state.getName());                mStateStack[i].state.enter();                mStateStack[i].active = true;            }                        mTransitionInProgress = false; // ensure flag set to false if no methods called        }     //--- from  handleMessage()     //此方法是主要的处理方法         private void performTransitions(State msgProcessedState, Message msg) {            /**             * If transitionTo has been called, exit and then enter             * the appropriate states. We loop on this to allow             * enter and exit methods to use transitionTo.             */             //orgState就是初始化节点            State orgState = mStateStack[mStateStackTopIndex].state;            ...             // 当前mDestState为null, 此mDestState为状态迁移的            State destState = mDestState;            if (destState != null) {                /**                 * Process the transitions including transitions in the enter/exit methods                 */                while (true) {                    if (mDbg) mSm.log("handleMessage: new destination call exit/enter");                    /**                     * Determine the states to exit and enter and return the                     * common ancestor state of the enter/exit states. Then                     * invoke the exit methods then the enter methods.                     */                    StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);                    // flag is cleared in invokeEnterMethods before entering the target state                    mTransitionInProgress = true;                    invokeExitMethods(commonStateInfo);                    int stateStackEnteringIndex = moveTempStateStackToStateStack();                    invokeEnterMethods(stateStackEnteringIndex);                    /**                     * Since we have transitioned to a new state we need to have                     * any deferred messages moved to the front of the message queue                     * so they will be processed before any other messages in the                     * message queue.                     */                    moveDeferredMessageAtFrontOfQueue();                    if (destState != mDestState) {                        // A new mDestState so continue looping                        destState = mDestState;                    } else {                        // No change in mDestState so we're done                        break;                    }                }                mDestState = null;            }            /**             * After processing all transitions check and             * see if the last transition was to quit or halt.             */            if (destState != null) {                if (destState == mQuittingState) {                    /**                     * Call onQuitting to let subclasses cleanup.                     */                    mSm.onQuitting();                    cleanupAfterQuitting();                } else if (destState == mHaltingState) {                    /**                     * Call onHalting() if we've transitioned to the halting                     * state. All subsequent messages will be processed in                     * in the halting state which invokes haltedProcessMessage(msg);                     */                    mSm.onHalting();                }            }        }

执行输出的Log:

D/hsm1    ( 1999): makeHsm1 ED/hsm1    ( 1999): ctor ED/hsm1    ( 1999): ctor XD/hsm1    ( 1999): mP1.enterD/hsm1    ( 1999): mS1.enterD/hsm1    ( 1999): makeHsm1 X

测试

分析完初始化流程,执行测试案例。

Hsm1 hsm = makeHsm1();synchronize(hsm) {//1     hsm.sendMessage(obtainMessage(hsm.CMD_1));//2          hsm.sendMessage(obtainMessage(hsm.CMD_2));     try {          // wait for the messages to be handled          hsm.wait();     } catch (InterruptedException e) {          loge("exception while waiting " + e.getMessage());     }}
  • 1 外部触发
    测试代码是通过sendMessage从外面进行触发,在状态机中是由mSmHandler进行处理。并将message加入到MessageQueue的消息队列中,会在handleMessage()中进行处理。
 @Override        public final void handleMessage(Message msg) {            if (!mHasQuit) {                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {                    //onPreHandleMessage是个空方法。子类可以自己实现                    mSm.onPreHandleMessage(msg);                }               //在初始化完成后mIsConstructionCompleted = true;               if (mIsConstructionCompleted || (mMsg.what == SM_QUIT_CMD)) {                    /** Normal path */                    msgProcessedState = processMsg(msg);                }                ...                //再执行完S1.processMessage后,当前的mDestState为mS1                performTransitions(msgProcessedState, msg);                // We need to check if mSm == null here as we could be quitting.                if (mDbg && mSm != null) mSm.log("handleMessage: X");                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {                    mSm.onPostHandleMessage(msg);                }            }        }        //--- from handleMessage        private final State processMsg(Message msg) {            //从初始状态开始            StateInfo curStateInfo = mStateStack[mStateStackTopIndex];            if (mDbg) {                mSm.log("processMsg: " + curStateInfo.state.getName());            }            if (isQuit(msg)) {                transitionTo(mQuittingState);            } else {                //从初始节点调用processMessage方法。                //如果当前节点可以处理跳过,如果当前节点不可处理。则调用父节点的processMessage方法                //如果一直迭代到根节点还是无法处理此msg。则调用unhandleMessage.表示无法处理此msg                while (!curStateInfo.state.processMessage(msg)) {                    /**                     * Not processed                     */                    curStateInfo = curStateInfo.parentStateInfo;                    if (curStateInfo == null) {                        /**                         * No parents left so it's not handled                         */                        mSm.unhandledMessage(msg);                        break;                    }                    if (mDbg) {                        mSm.log("processMsg: " + curStateInfo.state.getName());                    }                }            }            return (curStateInfo != null) ? curStateInfo.state : null;        }

上面的代码会执行到初始节点的processMessage方法,而初始节点的是mS1。我接着分析一下S1的代码。

    class S1 extends State {        @Override        public void enter() {            log("mS1.enter");        }                @Override         public boolean processMessage(Message message) {            log("S1.processMessage what=" + message.what);            if (message.what == CMD_1) {                //设置状态机的mDestState 为mS1                transitionTo(mS1);                // 返回true                return HANDLED;            } else {                // Let parent process all other messages                return NOT_HANDLED;            }        }        @Override         public void exit() {            log("mS1.exit");        }    }     //StateMachine.java        private final void transitionTo(IState destState) {            if (mTransitionInProgress) {                Log.wtf(mSm.mName, "transitionTo called while transition already in progress to " +                        mDestState + ", new target state=" + destState);            }            mDestState = (State) destState;            if (mDbg) mSm.log("transitionTo: destState=" + mDestState.getName());        }

S1中的方法中只是将状态机的mDestState设置为mS1, 接下来我们在回到hanldMessage方法中。顺着逻辑执行performTransitions()

        private void performTransitions(State msgProcessedState, Message msg) {            /**             * If transitionTo has been called, exit and then enter             * the appropriate states. We loop on this to allow             * enter and exit methods to use transitionTo.             */             //此处为mS1            State orgState = mStateStack[mStateStackTopIndex].state;            ...            //destState 为 mS1            State destState = mDestState;            if (destState != null) {                /**                 * Process the transitions including transitions in the enter/exit methods                 */                while (true) {                    if (mDbg) mSm.log("handleMessage: new destination call exit/enter");                    /**                     * Determine the states to exit and enter and return the                     * common ancestor state of the enter/exit states. Then                     * invoke the exit methods then the enter methods.                     */                     //从目标节点向查找跟当前节点共同的父节点。                    StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);                    // flag is cleared in invokeEnterMethods before entering the target state                    mTransitionInProgress = true;                    //从当前节点一直共同的父节点(不包含共同的父节点),执行exit()方法                    invokeExitMethods(commonStateInfo);                    int stateStackEnteringIndex = moveTempStateStackToStateStack();                    // 从共同的父节点一直到目标节点(不包含共同的父节点),执行enter方法                    invokeEnterMethods(stateStackEnteringIndex);                    /**                     * Since we have transitioned to a new state we need to have                     * any deferred messages moved to the front of the message queue                     * so they will be processed before any other messages in the                     * message queue.                     */                     //会将mDefer队列中的消息加到MessageQueue的头部。并清空                    moveDeferredMessageAtFrontOfQueue();                    if (destState != mDestState) {                        // A new mDestState so continue looping                        destState = mDestState;                    } else {                        // No change in mDestState so we're done                        break;                    }                }                mDestState = null;            }            /**             * After processing all transitions check and             * see if the last transition was to quit or halt.             */            if (destState != null) {                if (destState == mQuittingState) {                    /**                     * Call onQuitting to let subclasses cleanup.                     */                    mSm.onQuitting();                    cleanupAfterQuitting();                } else if (destState == mHaltingState) {                    /**                     * Call onHalting() if we've transitioned to the halting                     * state. All subsequent messages will be processed in                     * in the halting state which invokes haltedProcessMessage(msg);                     */                    mSm.onHalting();                }            }        }//--- from performTransitions//                            p1  //                           / \//       ^                 s0   s1//       |                /  \    \//       ^               s3   s4   s5 //       |              /      \//        destState -> s6       s7 <- currentState// 如果当前节点是s7 则[P1, s0, s4, s7]为激活的节点(ative = true),// 现在目标节点是s6,从s6往上一直查到s0为激活节点。        private final StateInfo setupTempStateStackWithStatesToEnter(State destState) {            /**             * Search up the parent list of the destination state for an active             * state. Use a do while() loop as the destState must always be entered             * even if it is active. This can happen if we are exiting/entering             * the current state.             */            mTempStateStackCount = 0;            StateInfo curStateInfo = mStateInfo.get(destState);            do {                mTempStateStack[mTempStateStackCount++] = curStateInfo;                curStateInfo = curStateInfo.parentStateInfo;            } while ((curStateInfo != null) && !curStateInfo.active);            if (mDbg) {                mSm.log("setupTempStateStackWithStatesToEnter: X mTempStateStackCount="                        + mTempStateStackCount + ",curStateInfo: " + curStateInfo);            }            return curStateInfo;        }//--- from performTransitions//                            p1  //                           / \//    commonStateInfo  -> s0   s1//                       /  \    \//                     s3   s4   s5 //                     /      \                   ^//      destState -> s6       s7 <- currentState  |//  从s7开始一直到s0为止,一路上的节点需要执行exit()方法,//  同时mStateStackTopIndex会向上移动,直到指向s0.        /**         * Call the exit method for each state from the top of stack         * up to the common ancestor state.         */        private final void invokeExitMethods(StateInfo commonStateInfo) {            while ((mStateStackTopIndex >= 0)                    && (mStateStack[mStateStackTopIndex] != commonStateInfo)) {                State curState = mStateStack[mStateStackTopIndex].state;                if (mDbg) mSm.log("invokeExitMethods: " + curState.getName());                curState.exit();                mStateStack[mStateStackTopIndex].active = false;                mStateStackTopIndex -= 1;            }        }//--- from performTransitions//    mStateEnterTopIndex   p1  //                      \  / \//    commonStateInfo  -> s0   s1//                       /  \    \//                     s3   s4   s5 //                     /      \     //      destState -> s6        s7 // 从mStateEnterTopIndex向下一直到s6执行enter()方法。        /**         * Invoke the enter method starting at the entering index to top of state stack         */        private final void invokeEnterMethods(int stateStackEnteringIndex) {            for (int i = stateStackEnteringIndex; i <= mStateStackTopIndex; i++) {                if (stateStackEnteringIndex == mStateStackTopIndex) {                    // Last enter state for transition                    mTransitionInProgress = false;                }                if (mDbg) mSm.log("invokeEnterMethods: " + mStateStack[i].state.getName());                mStateStack[i].state.enter();                mStateStack[i].active = true;            }            mTransitionInProgress = false; // ensure flag set to false if no methods called        }
Hsm1 hsm = makeHsm1();synchronize(hsm) {//1  这个执行完毕,状态机的mDestState = mS1;     hsm.sendMessage(obtainMessage(hsm.CMD_1));//2  目前执行到这个位置。     hsm.sendMessage(obtainMessage(hsm.CMD_2));     try {          // wait for the messages to be handled          hsm.wait();     } catch (InterruptedException e) {          loge("exception while waiting " + e.getMessage());     }}//根据前面的分析,会走到StateMachine的handleMessage,先执行S1.processMessage发现无法处理//交付给P1.processMessage进行处理。所以接下来分析P1的代码。    class P1 extends State {       @Override public void enter() {            log("mP1.enter");        }        @Override         public boolean processMessage(Message message) {            boolean retVal;            log("mP1.processMessage what=" + message.what);            switch(message.what) {            case CMD_2:                // CMD_2 will arrive in mS2 before CMD_3                //将CMD_3加到消息队列中                sendMessage(obtainMessage(CMD_3));                //将message(msg=CMD_2)加到defer队列中                deferMessage(message);                //将mDestState设置为mS2。                transitionTo(mS2);                retVal = HANDLED;                break;            default:                // Any message we don't understand in this state invokes unhandledMessage                retVal = NOT_HANDLED;                break;            }            return retVal;        }       @Override        public void exit() {            log("mP1.exit");        }    }//--- from handleMessage//将调用deferMessage的消息加到MessageQueue队列之前。        private final void moveDeferredMessageAtFrontOfQueue() {            /**             * The oldest messages on the deferred list must be at             * the front of the queue so start at the back, which             * as the most resent message and end with the oldest             * messages at the front of the queue.             */            for (int i = mDeferredMessages.size() - 1; i >= 0; i--) {                Message curMsg = mDeferredMessages.get(i);                if (mDbg) mSm.log("moveDeferredMessageAtFrontOfQueue; what=" + curMsg.what);                sendMessageAtFrontOfQueue(curMsg);            }            mDeferredMessages.clear();        }

以上执行是 hsm.sendMessage(obtainMessage(hsm.CMD_1)); 的流程,执行往后输出的log的如下:

D/hsm1    ( 1999): mS1.processMessage what=1D/hsm1    ( 1999): mS1.exitD/hsm1    ( 1999): mS1.enter

后面的代码 hsm.sendMessage(obtainMessage(hsm.CMD_2)); 也是走相同的流程,只不过需要结合不同的State中processMessage代码进行分析。

总结

综上整体的状态机流程如下:

  • 1 设置不同State之间的父子关系。
  • 2 设定初始State
  • 3 启动状态机
  • 4 重写State processMessage 定义状态切换的逻辑
  • 5 transitationTo() 来切换下一个目标状态
  • 6 可以通过deferMessage()来改变消息的处理优先级。

更多相关文章

  1. Android PopupWindow 隐藏软键盘的方法
  2. Android 访问Http被限制解决方法
  3. 禁止Edittext弹出系统软键盘 的几种方法
  4. Android Studio:正确引入so文件的方法
  5. android 学习五 设置应用程序全屏(没有状态栏和标题栏)
  6. Android studio编译时出现aapt.exe 崩溃的解决方法
  7. listView中item 图文并存的两种方法

随机推荐

  1. Android中 LogCat 信息消失
  2. 「Android」Lenovo K860 root脚本备忘
  3. Android中多线程的用法
  4. Ubuntu下eclipse连接手机
  5. Android手机客户端访问.NET服务器端的方
  6. android中配置文件property的用途以及使
  7. android UI - 仿威信tab样式
  8. android桌面悬浮窗显示录屏时间控制效果
  9. ListView去掉默认点击效果
  10. Why is Android(安卓)laggy, while iOS,