当前位置:操作系统 > 安卓/Android >>

android状态机statemachine详解

 
    先说两句题外话,很感谢android,在这里能看到很多优秀的代码。同时也感觉到外面的工程师真的很厉害,都是java人家就能写出这么牛的东西。感慨之下就有了些思考:我们绝大多数人只要把那些牛人已经创造出来的牛逼的东西,记住并且弄懂就是一件非常不错的事情,至少能衣食无忧。:-D 读书的时候需要经常做题,在理解的基础上记住解题方法基本就能很牛了,事实上高考中考绝大多数都是已经有过的题型,能做到前面所说的应该能进入不错的学校。工作后,慢慢也发现很多了不起的技术,都是在国外已经发展的很成熟基础上学习过来的。作为一个普通人,还是不要天天谈创新的好,hold不住,把基础的东西记住掌握即可。说了一堆,也算聊以易做图。
        我们知道类的成员可以分为两种:方法和属性。大多数情况下,对于一个状态,比如某数大于0,类的方法都只能做出一种对应的操作,并且类的本身并不考虑外部状态。android的状态机就属于大多数之后的那一小部分。对于某个事件,或者更准确的说,某一个消息,在不同的状态下能做出不同的操作。并且android状态机中的状态是继承的,就像数据结构中的树一样,如果当前节点(状态)不能对这个事件做出响应,就会到父节点继续判断并且做出响应,在下面的讲述中,我们称这个为状态路径,而对于所有状态称为状态树。这一句话已经从整体上对状态机进行了概括,记住这些对后面的理解很有好处。
        State,状态机中的状态封装类,这个类主要是实现了IState接口。其中有状态的基本方法,enter,exit以及消息处理方法processMessage。enter方法在状态机转入这个状态中会进行调用,exit方法在状态机转出这个方法时候会调用。这里对于一个很简单的类,google使用了接口属性,说说自己的理解。接口中的方法都是公有方法,并且只能声明常量。将主要方法都放在接口中声明,一方面限制了方法的定义,一方面也突出了这个类主要就是拥有某种功能。另外在State里面,声明了一个protect类型的构造方法,这样其他类就不可以直接声明state类的对象。state在状态机statemachine类里面是以StateInfo类型使用的,这个基本不影响访问。
statemachine里面主要工作都是由SmHandler类来完成的,statemachine本身绝大多数方法都是都是对SmHandler方法的再次封装。另外为了能够做到及时响应主线程的消息,又声明了一个HandlerThread,主要任务都是在这个线程里面实现的。
        现在直接去看SmHandler类吧,其最主要的方法就是handleMessage。该方法的主要是三大模块,第一个消息处理,或者说是分配到对应的状态再有对应的状态进行处理比较合适,第二个状态的初始化,大概可以理解成执行初始化状态路径上每个状态的enter方法,第三个执行状态转移,即更新状态树。

[java]

if (mIsConstructionCompleted) { 
    /** Normal path */ 
    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();//第三个执行状态转移 

            if (mIsConstructionCompleted) {
                /** Normal path */
                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();//第三个执行状态转移首先去看下processMsg方法

[java]

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) { 
        Log.d(TAG, "processMsg: " + curStateInfo.state.getName()); 
    } 

                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) {
           &nb

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,