Android消息机制(3)Handler

介绍

Handler的工作主要是信息的发送和处理,信息的发送通过post和send的一系列方法(实质上都是send),
处理则是通过覆盖handleMessage方法或实现Callback接口。接下来就来看一下Handler的关键方法吧。


send 和post

 public final boolean post(Runnable r){
       return  sendMessageDelayed(getPostMessage(r), 0);
 }
 private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
 }
 public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
 }
 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
       msg.target = this;
       if (mAsynchronous) {
           msg.setAsynchronous(true);
       }
       return queue.enqueueMessage(msg, uptimeMillis);
   }

可以看到,post方法通过把Runnable包装成Message,保存在callback属性中。最后和send一样调用的是sendMessageAtTime方法,再转到enqueueMessage方法后,Handler调用了MessageQueue的enqueueMessage把Message插入到了事件队列之中,并将指定Message处理对象的msg.target指定为自己。


dispatchMessage

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

从对Looper的分析知道,最后是Handler的dispatchMessage处理Message。dispatchMessage对Message的处理逻辑是,先看msg是否是post的Runnable转换过来的(callback属性),如果是就直接调用其的run方法;再看Handler是否实现了Callback接口(mCallback);如果没有,或者没有处理Message,最后再调用handleMessage方法。所以可以知道实现Callback接口的优先级是比覆盖handleMessage方法高的。
我们使用handler的常规方式是通过覆盖handleMessage方法,所以我们可以使用mCallback来拦截handler的特定message。我一时也想不到这种处理方式具体的使用场景,但我感觉,这种方式对于在多个handler中处理相同的message,或者采用策略模式在不同状态下通过不同mCallback来处理message,这些情况可能会有效果。


总结

到这里Handler,Looper,MessageQueue都已经看完了,分析一下这个机制最重要的功能——切换线程,是通过哪里完成的。当Handler的send方法被调用之后,enqueueMessage方法将Message插入消息队列,由Looper处理,这个时候还是在send方法调用处所在的线程里;而Looper是与线程绑定的,当Looper调用dispatchMessage的时候,就已经在Handler定义所在的线程了;所以线程切换在MessageQueue的enqueueMessage中,Looper调用其next方法在一个线程中读,enqueueMessage在另一个线程中插入,因此在enqueueMessage和next中用synchronized给MessageQueue加了锁,防止冲突。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值