handler looper 消息发送和消息处理流程

在Android系统中,消息的发送和处理通过Handler和Looper机制来完成的。

Looper主要负责消息机制的运转,就像VC++中有一个循环列表,在不停的接受消息,然后分发消息,至于消息怎么发送和发送到哪里都是由Handler来决定的。

Handler主要是对外提供消息发送和接收的接口,就是sendMessage(Message msg),dispatchMessage(Message msg),handlerMessage(Message msg)这三个函数。


通过查看Handler和Looper的source code可以发现,这两个类中都维护了一个消息队列final MessageQueue mQueue;

而这个消息队列其实就是Hanlder和Looper进行通信的纽带,我们可以简单的理解为:

当调用sendMessage函数时,其实是向消息队列添加了一条消息。

当调用dispatchMessage函数时,其实是从消息队列中取出了一条消息进行处理。

而Looper则启动了一个循环,在不停的检测有没有消息到了,如果有消息到来就调用Handler的dispatchMessage函数进行处理。

这样理解,我们就可以不用去管Handler和Looper的内部处理过程有多么的复杂,只需关注这两个消息发送和处理函数即可,在阅读代码的时候,也不用费很大力气去定位或查找消息的处理函数。


1. sendMessage ---- 消息发送函数,这个函数不用多说,就是发送消息,但是消息发送之后由谁处理,主要就是看发送的这个消息是怎么构成的,在dispatchMessage函数中会看到具体的处理过程。


2. dispatchMessage ---- 消息处理函数,不用外部进行显式的调用,Looper会在收到消息的时候会自动调用,进行消息处理。

查看dispatchMessage的源码发现,在调用handler的dispatchMessage函数时,根据不同的条件会调用不同的函数,而且也有优先级:

public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

    private final void handleCallback(Message message) {
        message.callback.run();
    }

1. 如果msg.callback != null,则执行handleCallback(msg);

    那么msg.callback是在什么时候赋值的呢?

    两个函数会对msg.callback进行赋值:

    1)public static Message obtain(Message orig) {
        Message m = obtain();
        m.what = orig.what;
        m.arg1 = orig.arg1;
        m.arg2 = orig.arg2;
        m.obj = orig.obj;
        m.replyTo = orig.replyTo;
        if (orig.data != null) {
            m.data = new Bundle(orig.data);
        }
        m.target = orig.target;
        m.callback = orig.callback;

        return m;
    }

    2)public static Message obtain(Handler h, Runnable callback) {
        Message m = obtain();
        m.target = h;
        m.callback = callback;

        return m;
    }

   所以在查看消息处理对应的函数时,一定要查看在构造消息的时候有没有调用以上两个函数中的一个,

   如果调用了,那么消息处理就会交由传递参数中message.callback.run()来处理。


2. 如果msg.callback == null,且mCallback != null,则由mCallback.handleMessage()来处理。

    那么mCallback是在什么时候赋值的呢?

    1). public Handler(Callback callback) {
        .................
        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;
    }

   2). public Handler(Looper looper, Callback callback) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
    }

3. 如果msg.callback == null,且mCallback == null,则由Handler自身的handleMessage()来处理。


总之,在判断调用哪个消息处理函数时,一定要先看是否在调用obtain构造消息的时候是不是传递了msg或Runable参数,如果没有,则判断在构造Handler时是否将Callback函数当作参数传递了进来,最后再看自己的Handler是否重写了handleMessage函数。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值