关闭

android StateMachine.java

341人阅读 评论(0) 收藏 举报
分类:

android 4.0.4: /frameworks/base/core/java/com/android/internal/util/StateMachine.java

StateMachine状态机中,会创建HandlerThread线程,和依附该线程的Handler;消息处理都是在HandlerThread中执行

framework层的好几个状态机,都是在StateMachine基础上实现的,比如:WifiStateMachine、DhcpStateMachine、WifiWatchdogStateMachine。。。

http://androidxref.com/4.0.4/xref/frameworks/base/core/java/com/android/internal/util/StateMachine.java

SmHandler:

       /**
         * Handle messages sent to the state machine by calling
         * the current state's processMessage. It also handles
         * the enter/exit calls and placing any deferred messages
         * back onto the queue when transitioning to a new state.
         */
        @Override
        public final void handleMessage(Message msg) {
            if (mDbg) Log.d(TAG, "handleMessage: E msg.what=" + msg.what);

            /** Save the current message */
            mMsg = msg;

            /**
             * Check that construction was completed
             */
            if (!mIsConstructionCompleted) {
                Log.e(TAG, "The start method not called, ignore msg: " + msg);//  在状态机没有启动之前,收到msg,只是打印error日志
                return;
            }


            /**
             * Process the message abiding by the hierarchical semantics
             * and perform any requested transitions.
             */
            processMsg(msg);
            performTransitions();

            if (mDbg) Log.d(TAG, "handleMessage: X");
        }


        /**
         * Complete the construction of the state machine.
         */
        private final void completeConstruction() {
            if (mDbg) Log.d(TAG, "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()) {
                int depth = 0;
                for (StateInfo i = si; i != null; depth++) {
                    i = i.parentStateInfo;
                }
                if (maxDepth < depth) {
                    maxDepth = depth;
                }
            }
            if (mDbg) Log.d(TAG, "completeConstruction: maxDepth=" + maxDepth);

            mStateStack = new StateInfo[maxDepth];
            mTempStateStack = new StateInfo[maxDepth];
            setupInitialStateStack();

            /**
             * Construction is complete call all enter methods
             * starting at the first entry.
             */
            mIsConstructionCompleted = true;
            mMsg = obtainMessage(SM_INIT_CMD);
            invokeEnterMethods(0);// 初始状态的enter方法,在调用线程中执行;即如果在UI线程中,调用状态机的start()方法,则初始状态的enter方法,在UI线程中执行,如果enter方法中有耗时的操作,肯定会占用UI线程的资源

            /**
             * Perform any transitions requested by the enter methods
             */
            performTransitions();// 如果初始状态的enter方法中,有跳转,即调用了transitionTo方法,则初始状态的exit方法、新状态的enter方法,也都会在调用线程中执行,依次类推,也会进一步占用调用线程的资源

            if (mDbg) Log.d(TAG, "completeConstruction: X");
        }

StateMachine:

    /**
     * Start the state machine.
     */
    public void start() {
        // mSmHandler can be null if the state machine has quit.
        if (mSmHandler == null) return;

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

///////////////////////////////////////////////////////////////////////////////////////////////////////////     

android 4.1.1: /frameworks/base/core/java/com/android/internal/util/StateMachine.java

http://androidxref.com/4.1.1/xref/frameworks/base/core/java/com/android/internal/util/StateMachine.java

SmHandler:

        /**
         * Handle messages sent to the state machine by calling
         * the current state's processMessage. It also handles
         * the enter/exit calls and placing any deferred messages
         * back onto the queue when transitioning to a new state.
         */
        @Override
        public final void handleMessage(Message msg) {
            if (mDbg) Log.d(TAG, "handleMessage: E msg.what=" + msg.what);

            /** Save the current message */
            mMsg = msg;

            if (mIsConstructionCompleted) {
                /** Normal path */
                processMsg(msg);
            } else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD) && (mMsg.obj == mSmHandlerObj)) {
                /** Initial one time path. */
                mIsConstructionCompleted = true;// 调用start方法,走该分支一次;后面处理消息,都走前面的分支processMsg;(在HandlerThread线程中执行)
                invokeEnterMethods(0);

            } else {
                throw new RuntimeException("StateMachine.handleMessage: " + "The start method not called, received msg: " + msg);//  这里也是修改点,状态机没有启动之前,即没有调用start()方法之前,在4.0.4上,是打印error日志;在4.1.1上,则是
            }
            performTransitions();

            if (mDbg) Log.d(TAG, "handleMessage: X");
        }


        /**
         * Complete the construction of the state machine.
         */
        private final void completeConstruction() {
            if (mDbg) Log.d(TAG, "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()) {
                int depth = 0;
                for (StateInfo i = si; i != null; depth++) {
                    i = i.parentStateInfo;
                }
                if (maxDepth < depth) {
                    maxDepth = depth;
                }
            }
            if (mDbg) Log.d(TAG, "completeConstruction: maxDepth=" + maxDepth);

            mStateStack = new StateInfo[maxDepth];
            mTempStateStack = new StateInfo[maxDepth];
            setupInitialStateStack();

            /** Sending SM_INIT_CMD message to invoke enter methods asynchronously */
            sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));// 不同于4.0.4,比如:在UI线程中,调用状态机的start方法,这里只是把SM_INIT_CMD消息发送给HandlerThread中的Handler处理,初始状态的enter、exit方法,都是在状态机的HandlerThread线程中执行的,不会占用UI线程的资源^-^算是一个小改进吧


            if (mDbg) Log.d(TAG, "completeConstruction: X");
        }

StateMachine:

    /**
     * Enqueue a message to the front of the queue for this state machine.
     * Protected, may only be called by instances of StateMachine.
     */
    protected final void sendMessageAtFrontOfQueue(int what, Object obj) {
        mSmHandler.sendMessageAtFrontOfQueue(obtainMessage(what, obj));
    }

0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:71657次
    • 积分:1014
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:49篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论