美文网首页
MessageQueue

MessageQueue

作者: 风吹过山 | 来源:发表于2017-05-17 16:11 被阅读0次

    我们知道Android提供了Handler 和 Looper 来满足线程间的通信,之前通过Handler和Looper的学习,知道

    1、子线程通过Handler对象来与Looper(一个线程可以产生一个Looper对象)沟通,

    2、push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。

    3、将消息放到Looper的MessageQueue中。

    4、Looper收到消息后就开始处理了,

    5、由Looper交由Handler处理,Handler最终将消息发送给主线程。

    那么我们今天就来讲讲MessageQueue!

    一:变量

    //mQuitAllowed表示MessageQueue是否允许退出,系统创建的UI线程的MessageQueue是不允许的,其他客户端代码创建的都是允许的;
    private final boolean mQuitAllowed;    
    
    //mPtr是native代码相关的,指向C/C++代码中的某些对象(指针)
    private long mPtr; // used by native code    
    
    //mMessages表示消息队列的头Head;
    Message mMessages;   
     
    //mIdleHandlers是IdldHandler接口的ArrayList, mPendingIdleHandlers是数组版本,在后面的代码中会将ArrayList的内容拷贝到它里面;
    private final ArrayList mIdleHandlers = new ArrayList();
    
    //IdleHandler接口表示当MessageQueue发现当前没有更多消息可以处理的时候则顺便干点别的事情的callback函数
    private IdleHandler[] mPendingIdleHandlers;
    
    //表示当前队列是否处于正在退出状态;
    private boolean mQuitting;
    // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
    
    //mBlocked表示next()调用是否被block在timeout不为0的pollOnce上;
    private boolean mBlocked;
    
    //mNextBarrierToken表示下一个barrier token,barrier用target==null, arg1==token的Message对象表示;
    private int mNextBarrierToken;
    //注:ctor中初始化mQuitAllowd和native的mPtr指针;
    

    二、方法
    MessageQueue作为Message存储的一个单链表,重要的是两个方法,enqueueMessage和next。enqueueMessage其主要操作是向MessageQueue单链表中插入数据。主要看一下next方法。
    通过代码片段:

    for (;;) {
                if (nextPollTimeoutMillis != 0) {
                    Binder.flushPendingCommands();
                }
    、、、
    
                            msg.next = null;
                            if (false) Log.v("MessageQueue", "Returning message: " + msg);
                            return msg;
                        }
    

    可以发现next是是一个无限循环的方法,唯一跳出循环的条件是取出MessageQueue中的msg,然后return msg (同时将Message从MessageQueue中移除)。如果MessageQueue 中没有消息,那么next方法将一直阻塞在这里,只有执行Loop.quit/quitSafely才会跳出循环。如果MessageQueue中有Message则执行msg.target.dispatchMessage(msg)。

    那么问题来了。。
    这里死循环了,那Activity怎么响应onCreate或者按钮的点击事件呢?

    Activity内部真正运行的是ActivityThread,ActivityThread的内部类H继承于Handler,通过handler消息机制,简单说Handler机制用于同一个进程的线程间通信。Activity的生命周期都是依靠主线程的Looper.loop,当收到不同Message时则采用相应措施:在H.handleMessage(msg)方法中,根据接收到不同的msg,执行相应的生命周期。也就是说这个死循环是为了给Activity处于一种时刻运行状态的机制。

    最后引申一下:
    从进程与线程间通信的角度,通过一张图加深大家对App运行过程的理解:

    yy.jpg

    结合图说说Activity生命周期,比如暂停Activity,流程如下:线程1的AMS中调用线程2的ATP;(由于同一个进程的线程间资源共享,可以相互直接调用,但需要注意多线程并发问题)线程2通过binder传输到App进程的线程4;线程4通过handler消息机制,将暂停Activity的消息发送给主线程;主线程在looper.loop()中循环遍历消息,当收到暂停Activity的消息时,便将消息分发给ActivityThread.H.handleMessage()方法,再经过方法的调用,最后便会调用到Activity.onPause(),当onPause()处理完后,继续循环loop下去。

    引申内容的作者:Gityuan

    相关文章

      网友评论

          本文标题:MessageQueue

          本文链接:https://www.haomeiwen.com/subject/kmudxxtx.html