如题,本文以第一视角带你领略Handler真正的风采
本人看大到机制这一主题的时候,通常会看猪脚的定义(简单翻译):
发送处理和一个Thread相关联的Message或者Runnable。每个Handler和一个Thread以及那个Thread中的MessageQueue相关联。每当你创建一个新的Handler的时候,他就被绑定在创建Handler的线程和对应的MessageQueue上。从那时候起,Handler发送的Runnable或者Message都被发送到那个对应的MessageQueue上。而当Message或者Runnable从MessageQueue上取出来的时候就执行他。
上面一段描述可以很明显的抽出几个重点
- Handler发送和接收的是Message或者Runnable
- 每个Handler实例关联到一个Thread和Thread对应的MessageQueue
- 当MessageQueue从队列中取出时,Handle会执行他
Handler发送和接收的是Message或者Runnable
Handler提供出来发送的方法如下
- post
- postDelayed
- sendMessage
- sendMessageDelayed
上面两个发送Runnable,下面两个发送Message。但,其实,提供上面两个是指丰富支持Runnable。最终会被封装成Message,发送到MessageQueue。
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;
}
// 封装成msg,发送到queue
return enqueueMessage(queue, msg, uptimeMillis);
}
每个Handler实例关联到一个Thread和Thread对应的MessageQueue
换句话,就是你通过一个Handler实例发送一个Message,他会找到对应的Thread中的MessageQueue并将Message插入。
关键来了,如果是你,你会怎么实现这么一个课题呢?
android系统的设计是:
设计一个Looper,每个线程都有自己的Looper。Looper管理MessageQueue。当Handler实例化的时候会有一个变量记录所在线程的looper。拿到looper就能拿到MessageQueue,接着就可以将Message插入MessageQueue。
当MessageQueue从队列中取出时,Handle会执行他
其实这句话包括2个课题,一个是取出(Looperd的loop方法会不断取出Message),一个是Handler的执行,这里我们先说Handler的执行。
如果是你,你如何让Handler在Message取出后,执行这个Message呢?换句话,如何找到这个Message对应的Handler并通知他?
android系统的设计是:
Message中添加了个字段:target 绑定对应的handler实例(插入MessageQueue的时候会进行判空,target为null抛出llegalArgumentException)。
最后,说一个大家很容易忽视的点。
public Handler(Callback callback, boolean async) {
mLooper = Looper.myLooper();
}
上面说到,Handler初始化的时候,通过持有引用mLooper的方式获取当前线程的Looper。那你有没有注意Looper的myLooper方法?
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
这个sThreadLocal就是ThreadLocal的应用,使每个线程都有这个变量的副本。
Handler初始化的时候通过持有引用的方式关联了Looper和对应的MessageQueue。并且Handler也记录了传进来的Callback。Handler发送Message到MessageQueue。Looper轮询MessageQueue取出Message,调用Message.target.dispatchMessage方法最终调用到Handler记录的Callback或者Message.callback。
网友评论