在Android中,handler消息随处可见,但是只会用却不知道是如何实现的,Looper和Handler之间又有什么联系呢?Android中的消息机制涉及到Looper、MessageQueue、Thread以及Handler,本篇将从源码来分析它们之间是如何建立的联系以及内部的工作机制是怎样的?
先来列一下所涉及到的代码路径:
Java层
framework/base/core/java/andorid/os/Looper.java
framework/base/core/java/andorid/os/MessageQueue.java
frameworks/base/core/java/android/os/Handler.java
frameworks/base/core/java/android/os/HandlerThread.java
Native层
frameworks/base/core/jni/android_os_MessageQueue.h
frameworks/base/core/jni/android_os_MessageQueue.cpp
system/core/libutils/include/utils/Looper.h
system/core/libutils/Looper.cpp
art/runtime/native/java_lang_Thread.cc
Handler
先从Android给的类的注释来看:
* A Handler allows you to send and process {
@link Message} and Runnable
* objects associated with a thread's {
@link MessageQueue}. Each Handler
* instance is associated with a single thread and that thread's message
* queue. When you create a new Handler, it is bound to the thread /
* message queue of the thread that is creating it -- from that point on,
* it will deliver messages and runnables to that message queue and execute
* them as they come out of the message queue.
简单总结一下上面的注释,Handler允许发送、处理和某个线程的MessageQueue相关联的Runnable对象集,每个Handler只能关联一个线程和消息队列,在创建线程的时候被绑定到上面,这时候就可以执行对应的逻辑了。
Handler主要有下面的两个作用
- 在某个时刻去处理Message;
- 在不同线程间处理action;
所以Handler主要就是去发送和处理Message,是一个具体任务处理的模块。
public Handler(@Nullable Callback callback, boolean async) {
...
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
Handler的构造函数会先获取Looper对象,然后通过Looper获得MessageQueue对象,并且将Callback存下来。
Looper
同理还是先从Android给的类的注释来看,looper是对线程用来循环运行一个消息,线程默认情况下没有和looper关联,直到用prepare创建,然后去run这个loop,一直等到loop被停掉。从给的注释来看,looper是需要thread来主动创建的。
* Class used to run a message loop for a thread. Threads by default do
* not have a message loop associated with them; to create one, call
* {
@link #prepare} in the thread that is to run the loop, and then
* {
@link #loop} to have it process messages until the loop is stopped.
这边Android也给了一个example来供读者参考:
* class LooperThread extends Thread {
* public Handler mHandler;
* public