美文网首页
2.消息事件分发

2.消息事件分发

作者: Varmin | 来源:发表于2017-06-02 00:00 被阅读0次

    什么是消息机制,概述:

    Android的消息机制主要是指Handler的运行机制,以及Handler所附带的MessageQueue和Looper的工作过程。即:消息的发送,以及消息的分发过程。

    为什么需要消息机制:

    Android规定访问UI只能在主线程中进行,在子线程中访问UI就会抛异常。但是Android又不建议在主线程中做耗时操作,会可能导致ANR。所以,我们需要,能在子线程中做完耗时操作,然后去到主线程更新UI的办法。
    Hander的主要作用是将一个任务切换到指定的线程中去执行。因此,系统提供Handler主要是为了解决在子线程中无法访问UI的问题。

    发送消息:

    handler中有众多的send方法,时间点的区别而已,到最后都会调用下面的方法,把message放入消息队列

    //handler.post  view.post中的参数都是一个runnable对象,分装成一个Message
    private static Message getPostMessage(Runnable r) {
            Message m = Message.obtain();
            m.callback = r;
            return m;
        }
    
    //msg插入队列 
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
            //注意此处,this指的是handler自己
            msg.target = this;
            if (mAsynchronous) {
                msg.setAsynchronous(true);
            }
            //把消息插入队列
            return queue.enqueueMessage(msg, uptimeMillis);
        }
        
    

    分发消息:

    loop将队列中的msg一个一个取出,分发到各自的handler中处理。handler根据是否有callback选择不同的分发方式。

    //Looper.loop(),省略了部分代码
    public static void loop() {
            final Looper me = myLooper();
            final MessageQueue queue = me.mQueue;
            //死循环。唤醒/挂起?
            for (;;) {
                //next方法会阻塞线程,有消息就取出,没消息就等待。
                Message msg = queue.next();
                //加入消息队列时,target == handler,分发的时候就可以找到原来的handler,让其自己处理。
                //所以,一个线程多个handler发送消息,虽然都在一个队列里,但是还是会分发到原来的handler处理消息。
                msg.target.dispatchMessage(msg);
            }
        }
        
    //由target返回到Handler中执行分发。
    //加入队列的:有的是Runnable封装的message,有的是callback,有的是message,在这里分发   
    public void dispatchMessage(Message msg) {
            //runnable封装的message。 handler.post/view.post
            if (msg.callback != null) {//msg中的callback 优先级1
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    //Handler(Callback callback)的时候,mCallback !=null
                    if (mCallback.handleMessage(msg)) {//handler中的callback,优先级2
                        return;
                    }
                }
                //正常的message那种形式,也即是new Handler时复写的方法。
                handleMessage(msg);// 优先级3
            }
        }
    

    优先级:依次降低。

    • 优先级1:
      view.post(runnable)和handler.post(runnable)。最后runnable都会分装成Message。分发的时候,在第一处调用。
    //封装成Message
    private static Message getPostMessage(Runnable r) {
            Message m = Message.obtain();
            m.callback = r;
            return m;
        }
        
    //分发调用
    //注意:虽然时runnable,但是,并不是新的线程哈。Thread的start()方法才是开启了新的线程,此处的run()就是正常的方法。   
    //Runnable中不要做耗时操作。
    private static void handleCallback(Message message) {
            message.callback.run();
        }
    
    • 优先级2:
      Handler(Callback callback)的时候,赋值,mCallback !=null。
      Callback的作用,源码中说明,就是用来创建一个Handler实例,但是并不需要派生Handler子类。提供了另外一种方式使用Handler。
      (不用派生Handler子类了,但是一样需要一个CallBack对象啊,并没有什么区别简化好嘛)。

    • 优先级3:
      就是那种常用的obtain一个Message,设置what,obj参数,发送的消息。

    退出:

    public static void loop() {
            //死循环。唤醒/挂起?
            for (;;) {
                //next方法会阻塞线程,有消息就取出,没消息就等待。
                Message msg = queue.next();
                if (msg == null) {
                    // No message indicates that the message queue is quitting.
                    return;
                }
                msg.target.dispatchMessage(msg);
            }
        }
    

    loop()是一个死循环,唯一跳出来的办法是消息队列的next方法返回null。否则,next方法会有消息就唤醒,取出msg分发,没消息就阻塞等待。

    分发机制

    图解

    • Handler通过sendMessage()发送Message到MessageQueue队列;
    • Looper通过loop(),不断提取出达到触发条件的Message,并将Message交给target来处理;
    • 经过dispatchMessage()后,交回给Handler的handleMessage()或者runnable来进行相应地处理。

    一个线程中的handler发送的消息,会不会跑到另外线程的MessageQueue队列中?

    不会的,线程,Looper,队列三者一一对应。

    一个线程间的多个handler发送消息,机制是怎样的?

    这多个handler发送的消息会在同一个消息队列中,但是加入队列时"msg.target = this",会在Looper分发消息时" msg.target.dispatchMessage(msg)",分发到原来的handler中处理。

    相关文章

      网友评论

          本文标题:2.消息事件分发

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