美文网首页
Handler、Looper、MessageQueue的关系

Handler、Looper、MessageQueue的关系

作者: Endless_123 | 来源:发表于2019-05-07 20:59 被阅读0次

    在日常开发中我们经常用到Handler,用来处理、传递消息而Handler中内部怎么实现,它与Looper、MessageQueue到底有什么关系确说不上来。

    先看下大体流程图:

    handler.jpg

    MessageQueue内部维护了一个Message的队列,我们通过Handler将消息Message发送到Looper中的MessageQueue,通过不断循环的Looper从MessageQueue中取出消息进行分发与执行。下面我们通过源码具体分析:

        //不传参数构造方法
        Handler handler = new Handler();
    

    最后会调用Handler中的这个构造方法

        public Handler(Callback callback, boolean async) {
            if (FIND_POTENTIAL_LEAKS) {
                final Class<? extends Handler> klass = getClass();
                if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                        (klass.getModifiers() & Modifier.STATIC) == 0) {
                    Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                        klass.getCanonicalName());
                }
            }
    
            mLooper = Looper.myLooper();
            if (mLooper == null) {
                throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
            }
            mQueue = mLooper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }
    

    在此构造方法主要对Handler 中的mLooper与mQueue赋值。
    mLooper = Looper.myLooper(); 获取的是当前线程的Looper
    mQueue获取的是Looper中的 MessageQueue。
    Handler发送消息

        handler.sendMessage()
    

    最后会调用Handler中

        private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
            msg.target = this;
            if (mAsynchronous) {
                msg.setAsynchronous(true);
            }
            return queue.enqueueMessage(msg, uptimeMillis);
        }
    

    在Handler中的enqueueMessage调用了MessageQueue中的enqueueMessage

     boolean enqueueMessage(Message msg, long when) {
           省略......      
            synchronized (this) {
                if (mQuitting) {
                    //线程退出 回收消息
                    msg.recycle();
                    return false;
                }
                //标记消息为再用状态
                msg.markInUse();
                //设置等待时长
                msg.when = when;
                Message p = mMessages;
                boolean needWake;
                if (p == null || when == 0 || when < p.when) {
                    // New head, wake up the event queue if blocked.
                    msg.next = p;
                    mMessages = msg;
                    needWake = mBlocked;
                } else {
                     needWake = mBlocked && p.target == null && msg.isAsynchronous();
                    Message prev;
                    for (;;) {
                        prev = p;
                        p = p.next;
                        if (p == null || when < p.when) {
                            break;
                        }
                        if (needWake && p.isAsynchronous()) {
                            needWake = false;
                        }
                    }
                    msg.next = p; // invariant: p == prev.next
                    prev.next = msg;
                }
    
                if (needWake) {
                    nativeWake(mPtr);
                }
            }
            return true;
        }
    

    这里主要将Message添加入队列
    最后在当前线程中Looper.loop()中处理Message

    public static void loop() {
            final Looper me = myLooper();
           ......
            for (;;) {
                Message msg = queue.next(); // might block
               ......
                try {
                    msg.target.dispatchMessage(msg);
                    end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
                } finally {
                    if (traceTag != 0) {
                        Trace.traceEnd(traceTag);
                    }
                }
              ......
           }
        }
    

    最后会调用msg.target.dispatchMessage(msg)分发消息,msg.target是传入的是Handler,所以最后会调用Handler的dispatchMessage方法分发。
    再说下Looper的启动,在我们的主线程UI线程中,Looper是由ActivityThread启动,我们在看下ActivityThread的main()方法
    /frameworks/base/core/java/android/app/ActivityThread.java

      public static void main(String[] args) {
            .....
            Looper.prepareMainLooper();
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
            
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
            ......
            Looper.loop();
            ......
    }
    

    我们可以看到在ActivityThread的main方法中实例化了ActivityThread,并且在主线程中调用Looper.prepareMainLooper();
    最后调用了Looper的prepare 方法

      private static void prepare(boolean quitAllowed) {
            if (sThreadLocal.get() != null) {
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(new Looper(quitAllowed));
        }
    

    在此方法为sThreadLocal 赋值实例化的Looper,在ActivityThread中最后调用Looper.loop(); 循环处理消息。
    从ActivityThread的main函数中可得知,如果在子线程使用Handler需要调用Looper.prepare() 后调用Looper.loop()才可以传递处理Message

    相关文章

      网友评论

          本文标题:Handler、Looper、MessageQueue的关系

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