Android消息机制——Handler

消息机制的定义

一个线程开启监听状态,其他线程对其发送消息,该线程根据消息进行对应的操作

消息机制中的Looper、Message、MessageQueue、Handler

  1. Looper:循环器,使线程处于无限循环状态(循环检查消息队列,主线程为Looper线程)
  2. Message:消息
  3. MessageQueue:消息队列,一个线程在某一时刻只能处理一个Message,所以需要保存起来并排队执行
  4. Handler:工作于两个线程之间,消息的发送与接收器

消息机制执行顺序

图解消息机制

  1. 工作线程:执行耗时工作(如下载图片),执行完毕后封装在一个Message对象中,使用Handler发送给Looper线程(放入该线程的MessageQueue中)
  2. Looper线程:循环遍历MessageQueue队列,将相应的Message分发给相应的Handler去处理
  3. 线程间可以共享资源,即工作线程可以直接访问MessageQueue(使用enQueue(Message msq)),但Google为了统一构造了Handler类(实际上该类也是获取MessgaeQueue)
  4. 实际上Activity启动也是基于消息机制的,Binder线程(属于工作线程,实际为ApplicationThread)在检测到activity要启动(或关闭)时,发送消息给主线程,主线程调用生命周期

Activity启动源码分析

启动源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public final class ActivityThread {
public static final void main(String[] args) {
......
Looper.prepareMainLooper();
......
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
......
Looper.loop();
......
}
}
  1. 首先执行的是Looper.prepareMainLooper();,该方法主要工作为创建Looper对象(使之持有MessageQueue、对应的线程),并保存在线程私有存储区(ThreadLocal)
  2. ActivityThread thread = new ActivityThread();此方法仅创建一个类,并非线程,thread.attach(false);,此方法创建Binder进程
  3. Looper.loop()方法获取当前线程的MessageQueue,并执行死循环,处理每一个Messsage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void loop() {
final Looper me = myLooper(); //获取TLS存储的Looper对象,获取当前线程的Looper
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue; //获取Looper对象中的消息队列
....
for (;;) { //主线程开启无限循环模式
Message msg = queue.next(); //获取队列中的下一条消息,可能会线程阻塞
if (msg == null) { //没有消息,则退出循环,退出消息循环,那么你的程序也就可以退出了
return;
}
....
//分发Message,msg.target 是一个Handler对象,哪个Handler把这个Message发到队列里,
//这个Message会持有这个Handler的引用,并放到自己的target变量中,这样就可以回调我们重写
//的handler的handleMessage方法。
msg.target.dispatchMessage(msg); //msg.target为Handler对象
....
....
msg.recycleUnchecked(); //将Message回收到消息池,下次要用的时候不需要重新创建,obtain()就可以了。
}
}

Handler源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
//不是static 发出可能内存泄露的警告!
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
//获取当前线程的Looper
//Looper.myLooper()内部实现可以先简单理解成:map.get(Thread.currentThread())
//获取当前线程的Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
//当前线程不是Looper 线程,没有调用Looper.prepare()给线程创建Looper对象
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//让Handler 持有当前线程消息队列的引用
mQueue = mLooper.mQueue;
//这些callback先不管,主要用于handler的消息发送的回调,优先级是比handlerMessage高,但是不常用
mCallback = callback;
mAsynchronous = async;
}

本文参考自Android 消息处理机制(Looper、Handler、MessageQueue,Message)