Android13 StatMachine start流程分析

StatMachine的start方法用于启动状态机,代码如下:

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private SmHandler mSmHandler;
    public void start() {
        // mSmHandler can be null if the state machine has quit.
        SmHandler smh = mSmHandler;
        if (smh == null) return;


        /** Send the complete construction message */
        smh.completeConstruction();
    }
}

SmHandler completeConstruction

调用SmHandler的completeConstruction方法:

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        /** Stack used to manage the current hierarchy of states */
        private StateInfo mStateStack[];
        /** A temporary stack used to manage the state stack */
        private StateInfo mTempStateStack[];
        /** The map of all of the states in the state machine */
        private HashMap<State, StateInfo> mStateInfo = new HashMap<State, StateInfo>();
        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.
             */
            int maxDepth = 0;
            for (StateInfo si : mStateInfo.values()) {  //遍历取出状态机中通过addState方法加入的,所有的状态。
                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);


            mStateStack = new StateInfo[maxDepth]; //创建StateInfo类型的数组,作为状态堆栈
            mTempStateStack = new StateInfo[maxDepth]; //创建StateInfo类型的数组,作为状态临时堆栈
            setupInitialStateStack();


            /** Sending SM_INIT_CMD message to invoke enter methods asynchronously */
            sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));


            if (mDbg) mSm.log("completeConstruction: X");
        }
    }
}

上面方法主要处理如下:

1、创建StateInfo类型的数组,作为状态堆栈

2、创建StateInfo类型的数组,作为状态临时堆栈

3、调用setupInitialStateStack方法,初始化堆栈

4、调用obtainMessage方法,获取消息并设置 Message.target 状态机处理程序、what 和 obj

5、调用sendMessageAtFrontOfQueue方法,发送SM_INIT_CMD消息

下面分别进行分析:

setupInitialStateStack

调用setupInitialStateStack方法,初始化堆栈:

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        /** The top of the mTempStateStack */
        private int mTempStateStackCount;
        /** A temporary stack used to manage the state stack */
        private StateInfo mTempStateStack[];
        private final void setupInitialStateStack() {
            if (mDbg) {
                mSm.log("setupInitialStateStack: E mInitialState=" + mInitialState.getName());
            }


            StateInfo curStateInfo = mStateInfo.get(mInitialState); //获取初始状态对应的StateInfo
            for (mTempStateStackCount = 0; curStateInfo != null; mTempStateStackCount++) {
                mTempStateStack[mTempStateStackCount] = curStateInfo; 
                curStateInfo = curStateInfo.parentStateInfo;
            }


            // Empty the StateStack
            mStateStackTopIndex = -1;


            moveTempStateStackToStateStack(); //将mTempStateStack[]数组的值倒序付给了mStateStack[]数组并且设置了  mStateStackTopIndex(栈顶序列号)的值为数组的最大下标,方便在ProcessMsg()时取出的state为栈顶元素。
        }
    }
}

  setupInitialStateStack(); 这个方法首先初始化了mTempStateStack[]数组()(树根保存在数组下标最大的那个元素上),然后又通过函数moveTempStateStackToStateStack()将mTempStateStack[]数组的值倒序付给了mStateStack[]数组并且设置了  mStateStackTopIndex(栈顶序列号)的值为数组的最大下标,方便在ProcessMsg()时取出的state为栈顶元素。

    mTempStateStack[]数组保存的是当前正在处理的树叶状态的所有父亲,且树根总是保存在数组下标最大的单元里;它是中间进行值操作所用的。

    mStateStack[]数组是mTempStateStack[]元素的反向保存,所以,树根永远保存在小标为0的单元里。且它是最终应用的state。

StateMachine obtainMessage

调用obtainMessage方法,获取消息并设置 Message.target 状态机处理程序、what 和 obj

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
        return Message.obtain(this, what, arg1, arg2, obj);
    }
}

Message obtain

调用Message的obtain方法,创建Message。

handleMessage

调用Handle的sendMessageAtFrontOfQueue方法,将SM_INIT_CMD消息排在消息队列的前面,以便在消息循环的下一次迭代中进行处理,发送的消息会在StateMachine的handleMessage方法中处理:

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
        /** true if construction of the state machine has not been completed */
        private boolean mIsConstructionCompleted;
//通过调用当前状态的 processMessage 来处理发送到状态机的消息。它还处理进入/退出调用,并在转换到新状态时将任何延迟的消息放回队列。
        @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; //将mIsConstructionCompleted 变量设置为true,目前是自调用invokeEnterMethods一次
                    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);
                }
            }
        }
   }
}

上面方法主要处理如下:

1、调用invokeEnterMethods方法,只在start时执行一次。

2、调用processMsg处理消息,消息包括SM_QUIT_CMD(调用quit或quitNow发送的消息,也包括调用sendMessage发送的消息)。

3、调用performTransitions方法,消息处理完毕状态切换,更新mStateStack。

下面分别进行分析:

invokeEnterMethods

调用invokeEnterMethods方法,从stateStackEnteringIndex向栈顶依次执行enter方法并设Active为true:

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        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(); //从stateStackEnteringIndex向栈顶依次执行enter方法
                mStateStack[i].active = true; //并设Active为true
            }
            mTransitionInProgress = false; // ensure flag set to false if no methods called
        }
    }
}

processMsg

调用processMsg处理消息,消息包括SM_QUIT_CMD(调用quit或quitNow发送的消息,也包括调用sendMessage发送的消息):

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        private final State processMsg(Message msg) {
            StateInfo curStateInfo = mStateStack[mStateStackTopIndex]; //从栈顶中取出当前StateInfo
            if (mDbg) {
                mSm.log("processMsg: " + curStateInfo.state.getName());
            }


            if (isQuit(msg)) {
                transitionTo(mQuittingState);
            } else {
                while (!curStateInfo.state.processMessage(msg)) { //调用当前StateInfo的state的processMessage方法
                    /**
                     * Not processed
                     */
                    curStateInfo = curStateInfo.parentStateInfo;  //如果当前状态的processMessage的返回为false,将curStateInfo赋值为当前状态的父状态的curStateInfo,然后继续调用父状态的processMessage方法
                    if (curStateInfo == null) { 
                        /**
                         * No parents left so it's not handled
                         */
                        mSm.unhandledMessage(msg); //直到没有父状态,调用unhandledMessage方法
                        break;
                    }
                    if (mDbg) {
                        mSm.log("processMsg: " + curStateInfo.state.getName());
                    }
                }
            }
            return (curStateInfo != null) ? curStateInfo.state : null;
        }
    }
}

performTransitions

调用performTransitions方法,消息处理完毕状态切换,更新mStateStack:

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        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.
             */
            State orgState = mStateStack[mStateStackTopIndex].state;


            /**
             * Record whether message needs to be logged before we transition and
             * and we won't log special messages SM_INIT_CMD or SM_QUIT_CMD which
             * always set msg.obj to the handler.
             */
            boolean recordLogMsg = mSm.recordLogRec(mMsg) && (msg.obj != mSmHandlerObj);


            if (mLogRecords.logOnlyTransitions()) {
                /** Record only if there is a transition */
                if (mDestState != null) {
                    mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
                            orgState, mDestState);
                }
            } else if (recordLogMsg) {
                /** Record message */
                mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState, orgState,
                        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); // 逐次向上查找destState的所有祖先直到该祖先的stateInfo.Active为true才停止,并将值放到mTempStateStake  里面,树根对应下标最大的,commonstateInfo为该祖先的    stateInfor属性,在这个函数里面也将mTempStateStake清空了,并重新赋值了
                    // flag is cleared in invokeEnterMethods before entering the target state
                    mTransitionInProgress = true;
                    invokeExitMethods(commonStateInfo); //从mStateStack的顶部依次向下移动直到找到commonStateInfo,把这些之间的state的exit方法都执行,并将Active赋值为false
                    int stateStackEnteringIndex = moveTempStateStackToStateStack(); //将mTempStateStack[]数组的值倒序付 给了mStateStack[]数组并且设置了   mStateStackTopIndex(栈顶序列号)的值为数组的最大下标。
                    invokeEnterMethods(stateStackEnteringIndex); //从stateStackEnteringIndex向栈顶依次执行enter方法并设Active为true


                    /**
                     * 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();
                }
            }
        }
    }
}

上面方法主要处理如下:

1、调用setupTempStateStackWithStatesToEnter方法,逐次向上查找destState的所有祖先直到该祖先的stateInfo.Active为true才停止,并将值放到mTempStateStake  里面,树根对应下标最大的,commonstateInfo为该祖先的    stateInfor属性,在这个函数里面也将mTempStateStake清空了,并重新赋值了。

2、调用invokeExitMethods方法,从mStateStack的顶部依次向下移动直到找到commonStateInfo,把这些之间的state的exit方法都执行,并将Active赋值为false。

3、调用moveTempStateStackToStateStack方法,将mTempStateStack[]数组的值倒序付 给了mStateStack[]数组并且设置了   mStateStackTopIndex(栈顶序列号)的值为数组的最大下标。

4、调用invokeEnterMethods方法,从stateStackEnteringIndex向栈顶依次执行enter方法并设Active为true。

下面分别进行分析:

setupTempStateStackWithStatesToEnter

调用setupTempStateStackWithStatesToEnter方法,逐次向上查找destState的所有祖先直到该祖先的stateInfo.Active为true才停止,并将值放到mTempStateStake  里面,树根对应下标最大的,commonstateInfo为该祖先的    stateInfor属性,在这个函数里面也将mTempStateStake清空了,并重新赋值了。

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        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;
        }
    }
}
invokeExitMethods

调用invokeExitMethods方法,从mStateStack的顶部依次向下移动直到找到commonStateInfo,把这些之间的state的exit方法都执行,并将Active赋值为false。

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        /**
         * 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;
            }
        }
    }
}
moveTempStateStackToStateStack

调用moveTempStateStackToStateStack方法,将mTempStateStack[]数组的值倒序付 给了mStateStack[]数组并且设置了   mStateStackTopIndex(栈顶序列号)的值为数组的最大下标。

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        /**
         * Move the contents of the temporary stack to the state stack
         * reversing the order of the items on the temporary stack as
         * they are moved.
         *
         * @return index into mStateStack where entering needs to start
         */
        private final int moveTempStateStackToStateStack() {
            int startingIndex = mStateStackTopIndex + 1;
            int i = mTempStateStackCount - 1;
            int j = startingIndex;
            while (i >= 0) {
                if (mDbg) mSm.log("moveTempStackToStateStack: i=" + i + ",j=" + j);
                mStateStack[j] = mTempStateStack[i];
                j += 1;
                i -= 1;
            }


            mStateStackTopIndex = j - 1;
            if (mDbg) {
                mSm.log("moveTempStackToStateStack: X mStateStackTop=" + mStateStackTopIndex
                        + ",startingIndex=" + startingIndex + ",Top="
                        + mStateStack[mStateStackTopIndex].state.getName());
            }
            return startingIndex;
        }
    }
}
invokeEnterMethods

调用invokeEnterMethods方法,从stateStackEnteringIndex向栈顶依次执行enter方法并设Active为true。

//frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
    private static class SmHandler extends Handler {
        /**
         * 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
        }
}
  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值