Android Handler之消息如何回到Handler(三)

续上两篇
有关Handler你想要的都在这里了(一)
有关Handler你想要的都在这里了(二)
上篇我们讲到了当我们调用handler.sendMessage()最终的执行效果是在MessageQueue中插入了一条消息,然后代码无法跟踪了,给我们的源码阅读带来了困难,因为我们的思路断了,接下来怎么办呢?
还记得我们在有关Handler你想要的都在这里了(一)中的第四部分怎么从主线程发送消息到子线程?(虽然这种应用场景很少)中的示例代码吗?
示例代码中有这么一行代码

//启动Looper循环
 Looper.loop();

我们为什么要写这一行代码呢?
这个时候就要静下心来想一下了,我们的Message已经存到了MessageQueue中,那么是不是接下来就应该取消息并且处理消息了?带着这样的疑问,我查看了loop()方法的源码

  public static void loop() {
        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            try {
                msg.target.dispatchMessage(msg);
            } 
        }
    }

同样的,为了降低阅读难度,我删掉了大部分的代码,只留下了这么几行核心代码,现在我们来看这几行代码的逻辑

这是一个死循环
这个循环的目的是从MessageQueue中取出消息
取消息的方法是MessageQueue.next()方法
取出消息后调用message.target对象的dispatchMessage()方法分发消息
循环跳出的条件是MessageQueue.next()方法返回了null

这也解释了为什么在子线程中要手动调用Looper.loop()方法
不过,看到这里我们应该自然会想到,message.target.是哪个对象?
该对象的dispatchMessage()方法都做了什么操作?
带着疑问,我们进入Message类中去寻找target

public final class Message implements Parcelable {
 /*package*/ int flags;

    /*package*/ long when;

    /*package*/ Bundle data;

    /*package*/ Handler target;

    /*package*/ Runnable callback;

    // sometimes we store linked lists of these things
    /*package*/ Message next;
}

看到了吧,Message类中有一个成员变量 target,而这个target是一个Handler,也就是说,在Looper从MessageQueue中取出Message之后,调用了Handler的dispatchMessage()方法。
这里我们不禁要问,这个target指向了哪个Handler?
带着这个疑问,我翻遍了Message类,也没有看到我想要的答案。此时我就想,既然Handler发送了消息就能接收到消息,那么会不会是在发送消息的途中发生了什么细节是我不知道的,那么我只好仔细看发送消息过程中的代码,终于让我发现了这个

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

在这个方法的第一行代码就是,将message的target属性赋值为发送message的handler自身。如果读者忘记了这个方法的调用时机,请仔细参阅本系列博客一、二。
也就是说,Looper取出消息后,调用了发送消息的Handler的dispatchMessage()方法,并且将message本身作为参数传了回去。到此时,代码的执行逻辑又回到了Handler中。
接着看handler的dispatchMessage()方法

 /**
    *handler的方法
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

看到这里面一个我们非常熟悉到方法了没有?—handleMessage()方法,对,这个方法就是我们经常要重写的handleMessage()方法,也是我们处理消息时候的逻辑。
到这里,Handler机制工作的主要流程就完成了。
接下来,我们就应该慢慢回答有关Handler的问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值