工作的时候发现自己对于很多东西用起来得心应手,原理机制也背诵的滚瓜烂熟,但是一问到源码脑子就....瓦特了!所以最近准备从头开始学习源码,学习大神们优秀的思想!
本文是对Handler机制的源码分析,目的是为了能够从源码角度一点点的理解Handler机制,里面会出现大量的源码,所以会比较枯燥,但是只要认真看完,相信你一定会对Handler机制的实现方法有更加清晰的认识
Handler是用起来非常简单!
点进去之后,我们会发现,sendEmptyMessage 、sendMessage 最终都是在调用 sendMessageAtTime 方法,将发送的消息放入messgeQueue;需要注意的一点是,sendMessageDelayed方法中,已经将 delayMillis 延迟时间转换成了 SystemClock.uptimeMillis() + delayMillis,指的是该消息被取出来执行的时间,这一点会在MessageQueue中显的比较重要
在sendMessageAtTime 方法中,消息放入了我们熟知的 handler机制中的MessageQueue;现在我们分析 sendMessageAtTime 方法,这个方法中主要执行了一个 MessageQueue 的非空判断,然后就直接执行了enqueueMessage方法,mQueue 是从哪里来的呢?为了逻辑的连贯性,此处先不分析,会放到下面进行分析,这里先接着enqueueMessage进行分析;
enqueueMessage方法也很简单,主要就是将此Hanlder赋值给Message,用来在分发消息时候接收消息的hanlder,然后将消息交给messageQueue来处理;
好了,到这里,我们开始进入messageQueue 了--
当然,并不是Handler源码已经分析完毕了,只是我按照代码的脚步一步一步的走下去,目的是为了让自己能清除的看到Handler机制走过的所有道路,以便于最终能够完整、清晰的理解Handler消息机制,最后还是会回到Handler中的;
直接找到 Handler中 enqueueMessage方法里面执行的MessageQueue方法, enqueueMessage(Message msg, long when);
本文是对Handler机制的源码分析,目的是为了能够从源码角度一点点的理解Handler机制,里面会出现大量的源码,所以会比较枯燥,但是只要认真看完,相信你一定会对Handler机制的实现方法有更加清晰的认识
Handler是用起来非常简单!
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//处理接收到的消息
}
};
初始化之后,在子线程进行完耗时操作之后,使用
handler.sendEmptyMessage(what)
好了,现在就从sendEmptyMessage 方法开始,一步步的解析handler整个工作流程 — — 注意,Handler开始向消息队列发送消息了;
点进去之后,我们会发现,sendEmptyMessage 、sendMessage 最终都是在调用 sendMessageAtTime 方法,将发送的消息放入messgeQueue;需要注意的一点是,sendMessageDelayed方法中,已经将 delayMillis 延迟时间转换成了 SystemClock.uptimeMillis() + delayMillis,指的是该消息被取出来执行的时间,这一点会在MessageQueue中显的比较重要
//直接调用 sendEmptyMessageDelayed 方法
public final boolean sendEmptyMessage(int what){
//直接调用 sendEmptyMessageDelayed 方法
return sendEmptyMessageDelayed(what, 0);
}
// 被sendEmptyMessage方法调用,delayMillis 为0,同时将参数转换成message后调用 sendMessageDelayed 此处已经和 sendMessage方法调用同一个路径了
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
//将参数进行复制,转换成 Message
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
//此处的 SystemClock.uptimeMillis() + delayMillis 用来计算消息的执行时间
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
//最终,发送消息的方法都会走到这里,将消息放入MessageQueue
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
//mQueue 是从哪里来的?此处先放下,待会回头来分析
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);
}
在sendMessageAtTime 方法中,消息放入了我们熟知的 handler机制中的MessageQueue;现在我们分析 sendMessageAtTime 方法,这个方法中主要执行了一个 MessageQueue 的非空判断,然后就直接执行了enqueueMessage方法,mQueue 是从哪里来的呢?为了逻辑的连贯性,此处先不分析,会放到下面进行分析,这里先接着enqueueMessage进行分析;
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//将此Hanlder赋值给Message,用来在分发消息时候接收消息的hanlder
msg.target = this;
if (mAsynchronous) {//是否是异步,此处为false,不会执行
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
enqueueMessage方法也很简单,主要就是将此Hanlder赋值给Message,用来在分发消息时候接收消息的hanlder,然后将消息交给messageQueue来处理;
好了,到这里,我们开始进入messageQueue 了--
当然,并不是Handler源码已经分析完毕了,只是我按照代码的脚步一步一步的走下去,目的是为了让自己能清除的看到Handler机制走过的所有道路,以便于最终能够完整、清晰的理解Handler消息机制,最后还是会回到Handler中的;
现在,我们进入MessageQueue — — 注意:Handler发送的消息,要进入消息队列了;
直接找到 Handler中 enqueueMessage方法里面执行的MessageQueue方法, enqueueMessage(Message msg, long when);
boolean enqueueMessage(Message msg, long when) {
// msg.target ,这个参数是不是很熟悉,对的,就是在Handler进入MessageQueue之前的enqueueMessage方法中赋值的,是当前的Handler
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {//此处判断当前Message是否是被执行了,一个消息不能被执行使用两次
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
if (mQuitting) {//mQuitting默认一直是false,只有执行quit 方法,并且该MessageQueue能被安全退出的时候回被赋值为true,主线程中是不能被退出的,所以一直都是false,因此不会被执行进来ÿ