0. 前言
做 Android 开发肯定离不开跟 Handler 打交道,它通常被我们用来做主线程与子线程之间的通信工具,而 Handler 作为 Android 中消息机制的重要一员也确实给我们的开发带来了极大的便利。
可以说只要有异步线程与主线程通信的地方就一定会有 Handler。
那么,Handler 的通信机制的背后的原理是什么?
本文带你揭晓。
注:本文所展示的系统源码基于 Android-27 ,并有所删减。
本文首发掘金:Handler 都没搞懂,拿什么去跳槽
作者:程序亦非猿
1. 重识 Handler
我们可以使用 Handler 发送并处理与一个线程关联的 Message 和 Runnable 。(注意:Runnable 会被封装进一个 Message,所以它本质上还是一个 Message )
每个 Handler 都会跟一个线程绑定,并与该线程的 MessageQueue 关联在一起,从而实现消息的管理以及线程间通信。
1.1 Handler 的基本用法
android.os.Handler handler = new Handler(){
@Override
public void handleMessage(final Message msg) {
//这里接受并处理消息
}
};
//发送消息
handler.sendMessage(message);
handler.post(runnable);
实例化一个 Handler 重写 handleMessage
方法 ,然后在需要的时候调用它的 send
以及 post
系列方法就可以了,非常简单易用,并且支持延时消息。(更多方法可查询 API 文档)
但是奇怪,我们并没有看到任何 MessageQueue 的身影,也没看到它与线程绑定的逻辑,这是怎么回事?
2. Handler 原理解析
相信大家早就听说过了 Looper 以及 MessageQueue 了,我就不多绕弯子了。
不过在开始分析原理之前,先明确我们的问题:
- Handler 是如何与线程关联的?
- Handler 发出去的消息是谁管理的?
- 消息又是怎么回到 handleMessage() 方法的?
- 线程的切换是怎么回事?
2.1 Handler 与 Looper 的关联
实际上我们在实例化 Handler 的时候 Handler 会去检查当前线程的 Looper 是否存在,如果不存在则会报异常,也就是说在创建 Handler 之前一定需要先创建 Looper 。
代码如下:
public Handler(Callback callback, boolean async) {
//检查当前的线程是否有 Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//Looper 持有一个 MessageQueue
mQueue = mLooper.mQueue;
}
这个异常相信很多同学遇到过,而我们平时直接使用感受不到这个异常是因为主线程已经为我们创建好了 Looper,先记住,后面会讲。(见【3.2】)
一个完整的 Handler 使用例子其实是这样的:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
Looper.prepare() :
//Looper
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
Looper 提供了 Looper.prepare()
方法来创建 Looper ,并且会借助 ThreadLocal 来实现与当前线程的绑定功能。Looper.loop() 则会开始不断尝试从 MessageQueue 中获取 Message , 并分发给对应的 Handler(见【2.3】)。
也就是说 H