Handler,Message,MessageQueue,Looper源码解析

Handler

/**
Handler允许你提交并处理message或者和线程的MessageQueue相关联的Runnable对象。每一个Handler实例都和一个单独的线程以及这个线程的messge queue相关联。
当创建一个新的Handler,它就和创建了它的线程和线程创建的message queue绑定,这时候,它会传递messages和runnables到message queue,然后从message queue中取出来执行他们。

有两个主要用途1.调度messages和runnables在将来的某个时间点执行。2.在不同于你的线程里插入一个action等待被执行

messages通过调用post,postAtTime(Runnable, long),postDelayed,sendEmptyMessage,sendMessage,sendMessageAtTime,sendMessageDelayed这些方法来完成。
post系列方法允许在message queue中排列等待被调用Runnable对象;sendMessage系列方法允许排列那些将在Handler的handleMessage方法(前提是子类化了Handler)中被执行的包含bundle数据的message对象

当提交给handler,可以在message queue准备完毕之后立刻执行,或者指定一个延迟时间再执行,或绝对时间再执行。对于后两者,可以实现超时,ticks, 和其他基于时间的行为.

当应用的一个进程被创建,主线程专门用来运行一个负责管理top-level应用对象(activities, broadcast receivers,等)和这些应用创建的窗口的messge queue。
你可以创建自己的线程,然后通过一个Handler来和主应用线程通信,只需要像之前一样调用post或sendMessage方法,但是是在你的新线程。被提交的Runnable或Message会被安排到这个Handler的message queue然后在适当的时间处理。
*/

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
如果当前线程没有looper,那么这个handler不能接受message,而且会抛出一个异常。
*/

public Handler() {
this(null, false);
}

public Handler(Callback callback) {
this(callback, false);
}

/**
使用提供的Looper而不是默认的,looper不能为空
*/

public Handler(Looper looper) {
this(looper, null, false);
}

public Handler(Looper looper, Callback callback) {
this(looper, callback, false);//第三个参数默认同步的
}

/**
设置handler是否应该是异步的
Handler默认是同步的除非构造函数明确说明使用异步
异步消息表示不需要全局顺序的中断或事件来表示同步消息。异步消息不受由MessageQueue#enqueueSyncBarrier(long)同步barriers限制
当async是true,handler会给发送给它的Message或者提交给他的Runnable调用Message的setAsynchronous(boolean)。
* @hide
*/

public Handler(boolean async) {
this(null, async);
}

/**
* @hide
*/

public Handler(Callback callback, boolean async) {
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());
}
}

mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
/*
设置这个flag为true来检测继承的Handler是否是匿名,局部或成员类,而且不是静态
这些类型的可能会造成泄露
*/

private static final boolean FIND_POTENTIAL_LEAKS = false;

/**
当初始化一个Handler时避免必须实现你自己的Handler子类时,你可以使用这个回调接口
@return True 如果不需要进一步处理
*/

public interface Callback {
public boolean handleMessage(Message msg);
}

/**
子类必须实现这个方法来接受messages
*/

public void handleMessage(Message msg) {
}

/**
处理系统messages
*/

public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {//如果不需要进一步处理,返回true
return;
}
}
handleMessage(msg);
}
}

private static void handleCallback(Message message) {
message.callback.run();
}

/**从全局的message池中返回一个新的Message,比创建分配一个新的实例更高效。
检索到的消息让它的handler指向这个实例(Message.target == this).
如果你不需要这个能力,那就用Message.obtain()代替
*/

public final Message obtainMessage(){
return Message.obtain(this);
}

/**
在返回的message里设置what值
*/

public final Message obtainMessage(int what){
return Message.obtain(this, what);
}

/**
* @hide
*/

public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}

/**
将Runnable添加到message queue中,这个被添加的Runnable会在这个handler附属的线程运行
如果失败返回false,通常是因为处理message queue的looper退出了
*/

public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}

//将Runnable放到message的callback中,在Handler的dispatchMessage中被处理
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}

/**
在message queue的下一个迭代会执行这个Runnable
这个方法只有在非常特殊的情况下才会使用,它很容易饿死message queue,引起顺序问题或者其他不可预期的副作用
*/

public final boolean postAtFrontOfQueue(Runnable r){
return sendMessageAtFrontOfQueue(getPostMessage(r));
}


public final boolean sendMessageAtFrontOfQueue(Message msg) {
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, 0);
}
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
29
30
31
32
33

/**
同步运行指定的任务
如果当前线程是handler线程,那么runnable会直接运行而不必插入队列,否则,提交runnable到handler并且在返回之前等待它完成。

这个方法很危险!不恰当的使用会引起死锁。当任何锁被持有的时候千万不能调用这个方法或者在可以重入的方法中也不能使用。
这个方法在以下场景偶尔有用:当一个后台线程必须同步的等待一个必须在handler的线程中运行的任务的完成。但是这个问题通常是不良设计的症状。在使用这个方法之前首先考虑改进设计(如果可能)

使用这个方法的一个可能:当你只是创建一个Handler线程而且需要在继续执行之前执行一些初始化步骤
超时之后返回false但是runnable仍然被提交到handler而且也许在稍后的时间已经准备或已经完成

使用了这个方法,确定要使用quitSafely来退出looper.否则runWithScissors会无限期挂起
TODO:我们应该通过将MessageQueue改为blocking runnables的方

@hide
这个方法容易滥用而且不应该出现在API中。即使我们让它成为API的一部分,我们也会用类似runUnsafe()来重命名
*/

public final boolean runWithScissors(final Runnable r, long timeout) {
if (r == null) {
throw new IllegalArgumentException("runnable must not be null");
}
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be non-negative");
}

if (Looper.myLooper() == mLooper) {
r.run();
return true;
}

BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}

以下是BlockingRunnable的实现

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private static final class BlockingRunnable implements Runnable {
private final Runnable mTask;
private boolean mDone;

public BlockingRunnable(Runnable task) {
mTask = task;
}

@Override
public void run() {
try {
mTask.run();
} finally {
synchronized (this) {
mDone = true;
notifyAll();
}
}
}

public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) {
return false;
}

synchronized (this) {
if (timeout > 0) {
final long expirationTime = SystemClock.uptimeMillis() + timeout;
while (!mDone) {
long delay = expirationTime - SystemClock.uptimeMillis();
if (delay <= 0) {
return false; // timeout
}
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) {
try {
wait();
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/** 
在所有待执行的messages之后,在(current time + delayMillis)之前将msg插入到message queue中。会在handler附属的线程里边的handleMessage方法中收到
如果返回true,不一定意味着message将会被执行,如果looper在message传递时间发生之前退出,message会被丢掉。
*/

public final boolean sendMessageDelayed(Message msg, long delayMillis){
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
/**
在所有待执行的messages之后,在绝对时间(毫秒)uptimeMillis之前将msg插入到message queue中
时间基准是android.os.SystemClock#uptimeMillis
*/

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;
}
return enqueueMessage(queue, msg, uptimeMillis);
}

最终调用message queue的enqueueMessage

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
/**
移除所有在message queue里边准备提交的Runnable
*/

public final void removeCallbacks(Runnable r){
mQueue.removeMessages(this, r, null);
}

/**
移除所有message queue里包含what的message
*/

public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}

public final boolean sendMessage(Message msg){
return sendMessageDelayed(msg, 0);
}

/**
发送一个只包含what值的message
*/

public final boolean sendEmptyMessage(int what){
return sendEmptyMessageDelayed(what, 0);
}

public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}



final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}

private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
Handler.this.sendMessage(msg);
}
}

Message

/*
定义一个可以发送给Handler的message,这个message可以包含一个描述和任意数据对象。这个对象包含两个额外的int域和一个额外的对象域,这样在很多情况下就不必再分配
虽然构造方法是public,但是最好的方式得到一个message是调用Message.obtain()或者Handler.obtainMessage(),这些方法会从一个循环的对象池中取出他们
/

/*
一个任意的对象
当使用Messager在进程间发送message时,如果包含一个Parcelable的一个框架类(不是由系统实现),这是唯一不能为空的
/

public Object obj;

/**

  • Optional Messenger where replies to this message can be sent. The
  • semantics of exactly how this is used are up to the sender and
  • receiver.
    */

public Messenger replyTo;

// 有些时候我们以链表形式存储他们
/package/ Message next;

private static Message sPool;
private static final int MAX_POOL_SIZE = 50;
private static final Object sPoolSync = new Object();

当看到以下代码是感觉到大学的数据结构没白学啊。但是为什么不使用现成的Queue呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
从一个全局的池中返回一个Message实例。在很多情况下可以避免分配新的对象。
*/

public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
sPoolSize--;
return m;
}
}
return new Message();
}

public静态方法,加上同步块保证线程安全,sPool不为空的时候,声明一个引用指向它,然后将它的下一个message赋给sPool,这时候sPool指向链表的第二个,把将要取出的m的下一个next置空,池大小减1,然后返回m。(这时候sPool有可能变为null)

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
和obtain()方法类似,只是复制这个messge到一个新的里边
*/

public static Message obtain(Message orig) {
Message m = obtain();
m.what = orig.what;
m.arg1 = orig.arg1;
m.arg2 = orig.arg2;
m.obj = orig.obj;
m.replyTo = orig.replyTo;
if (orig.data != null) {
m.data = new Bundle(orig.data);
}
m.target = orig.target;
m.callback = orig.callback;

return m;
}

/**
返回一个message实例到全局池中。在调用这个方法之后,不能再碰这个Message,它已经有效的被释放了
*/

public void recycle() {
clearForRecycle();

synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}

void clearForRecycle() {
flags = 0;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
when = 0;
target = null;
callback = null;
data = null;
}
/**
* 设置message是否是异步的。
* Asynchronous messages represent interrupts or events that do not require global ordering
* with represent to synchronous messages. Asynchronous messages are not subject to
* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
* 异步消息表示不需要全局顺序的中断或事件来表示同步消息。
*

*
* @hide
*/

public void setAsynchronous(boolean async) {
if (async) {
flags |= FLAG_ASYNCHRONOUS;
} else {
flags &= ~FLAG_ASYNCHRONOUS;
}
}

Messenger

/*
它引用了一个Handler对象,以便others能够向它发送消息.该类允许跨进程间基于Message的通信,通过创建一个Messenger指向一个进程中的Handler,然后在另一个进程中操作那个Messenger.
/
private final IMessenger mTarget;

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
/**
* @param target 接收发送的messages
创建一个新的Messenger指向给定的Handler.任何通过这个Messenger发送的Message对象会出现在Handler中,就像Handler中sendMessage(Message)被直接调用
*/

public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
/**
给Messenger的Handler发送一个Message,
*/

public void send(Message message) throws RemoteException {
mTarget.send(message);
}

/**
* 两个Messenger的mTarget.asBinder()指向相同内容即为相同
*/

public boolean equals(Object otherObj) {
if (otherObj == null) {
return false;
}
try {
return mTarget.asBinder().equals(((Messenger)otherObj)
.mTarget.asBinder());
} catch (ClassCastException e) {
}
return false;
}

MessageQueue

/**
Low-level的类持有通过Looper来分发的message列表。Messages不要直接添加到MessageQueue中,而是通过和Looper相关联的Handler对象

在当前线程可以通过Looper.myQueue()来检索MessageQueue.
*/

// 表明next()是否在pollOnce()中阻塞等待一个非0的超时时间
private boolean mBlocked;

// 下一个barrier token
// Barriers这样被声明:message的target是null,而且arg1域保存着token值
private int mNextBarrierToken;

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
/**
当一个线程将要阻塞等待更多messages的时候回调此接口
*/

public static interface IdleHandler {
/**
当message queue运行完messages后等待更多信息时调用这个接口。返回true来保持你的idle handler激活状态,返回false移除激活状态。如果仍然有pending 的messages在queue中,但是他们都是在当前时间之后才会被调度分配的,这个就有可能会被调用
*/

boolean queueIdle();
}

/**
在messge queue中添加一个新的IdleHandler。如果从IdleHandler.queueIdle()中返回false会自动移除,或者使用removeIdleHandler来明确移除。

线程安全的
*/

public void addIdleHandler(IdleHandler handler) {
if (handler == null) {
throw new NullPointerException("Can't add a null IdleHandler");
}
synchronized (this) {
mIdleHandlers.add(handler);
}
}
/**
从queue中移除先前调用addIdleHandler添加的IdleHandler。
*
* @param handler The IdleHandler to be removed.
*/

public void removeIdleHandler(IdleHandler handler) {
synchronized (this) {
mIdleHandlers.remove(handler);
}
}

MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
然而对消息队列而言,在摘取消息时还要考虑更多技术细节。它关心的细节有:

1)如果消息队列里目前没有合适的消息可以摘取,那么不能让它所属的线程“傻转”,而应该使之阻塞;
2)队列里的消息应该按其“到时”的顺序进行排列,最先到时的消息会放在队头,也就是mMessages域所指向的消息,其后的消息依次排开;
3)阻塞的时间最好能精确一点儿,所以如果暂时没有合适的消息节点可摘时,要考虑链表首个消息节点将在什么时候到时,所以这个消息节点距离当前时刻的时间差,就是我们要阻塞的时长。
4)有时候外界希望队列能在即将进入阻塞状态之前做一些动作,这些动作可以称为idle动作,我们需要兼顾处理这些idle动作。一个典型的例子是外界希望队列在进入阻塞之前做一次垃圾收集。
Message next() {
int pendingIdleHandlerCount = -1; // 只有在第一次迭代中为-1
int nextPollTimeoutMillis = 0;
for (;;) {//死循环
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}

//我们可以假设mPtr != 0 因为loop显然还在运行。
//looper在loop退出之后不会调用这个方法
nativePollOnce(mPtr, nextPollTimeoutMillis);

synchronized (this) {
//尝试检索下一个message,找着就返回
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
//习惯将类变量赋值给局部变量再进行操作。
Message msg = mMessages;
if (msg != null && msg.target == null) {
// 如果从队列里拿到的msg是个“同步分割栏”,那么就寻找其后第一个“异步消息”
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
//下一个message还没有准备好,设置一个超时时间当它准备好之后唤醒
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
msg.markInUse();
return msg;
}
} else {
// 没有messges了
nextPollTimeoutMillis = -1;
}

//既然所有的messagess已经被处理完毕那就处理退出message
if (mQuitting) {
dispose();
return null;
}

// 如果第一时间空闲,获取到闲置的数量来运行
// 闲置的handles只有在queue是空的时候或者queue里第一个message(也许是个barrier)定于一段时间之后执行。
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
// 没有闲置的handler。loop并等待更多的
mBlocked = true;
continue;
}

if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}

// 运行空闲的handlers.只在第一个迭代中,我们才会运行到这段代码块
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null; // 释放handler引用
boolean keep = false;
try {
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf("MessageQueue", "IdleHandler threw exception", t);
}

if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}

// 重新设置闲置handler数量为0,我们不再运行他们
pendingIdleHandlerCount = 0;

// 当调用一个闲置的handler时,一条新的message可能已经传递到,所以go back,立刻看一下那条消息
nextPollTimeoutMillis = 0;
}
}
这个函数里的for循环并不是起循环摘取消息节点的作用,而是为了连贯“当前时间点”和“处理下一条消息的时间点”。简单地说,当“定时机制”触发“摘取一条消息”的动作时,会判断事件队列的首条消息是否真的到时了,如果已经到时了,就直接返回这个msg,而如果尚未到时,则会努力计算一个较精确的等待时间(nextPollTimeoutMillis),计算完后,那个for循环会掉过头再次调用到nativePollOnce(mPtr, nextPollTimeoutMillis),进入阻塞状态,从而等待合适的时长。

next()里另一个要说的是那些Idle Handler,当消息队列中没有消息需要马上处理时,会判断用户是否设置了Idle Handler,如果有的话,则会尝试处理mIdleHandlers中所记录的所有Idle Handler,此时会逐个调用这些Idle Handler的queueIdle()成员函数。我们举一个例子,在ActivityThread中,在某种情况下会在消息队列中设置GcIdler,进行垃圾收集,其定义如下:

final class GcIdler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
doGcIfNeeded();
return false;
}
}
一旦队列里设置了这个Idle Handler,那么当队列中没有马上需处理的消息时,就会进行垃圾收集。


void quit(boolean safe) {
if (!mQuitAllowed) {
throw new RuntimeException("Main thread not allowed to quit.");
}

synchronized (this) {
if (mQuitting) {
return;
}
mQuitting = true;

if (safe) {
removeAllFutureMessagesLocked();
} else {
removeAllMessagesLocked();
}

// We can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}

private void removeAllMessagesLocked() {
Message p = mMessages;
while (p != null) {//将所有message清空
Message n = p.next;
p.recycle();
p = n;
}
mMessages = null;
}

private void removeAllFutureMessagesLocked() {
final long now = SystemClock.uptimeMillis();
Message p = mMessages;
if (p != null) {
if (p.when > now) {//队列中下一个要执行的都在当前时间之后才执行,直接移除。
removeAllMessagesLocked();
} else {//否则将执行时间大于当前时间之后的message都清空。
Message n;
for (;;) {
n = p.next;
if (n == null) {
return;
}
if (n.when > now) {
break;
}
p = n;
}
p.next = null;
do {
p = n;
n = p.next;
p.recycle();
} while (n != null);
}
}
}

/*所谓“同步分割栏”,可以被理解为一个特殊Message,它的target域为null。它不能通过sendMessageAtTime()等函数打入到消息队列里,而只能通过调用Looper的postSyncBarrier()来打入。

“同步分割栏”是起什么作用的呢?它就像一个卡子,卡在消息链表中的某个位置,当消息循环不断从消息链表中摘取消息并进行处理时,一旦遇到这种“同步分割栏”,那么即使在分割栏之后还有若干已经到时的普通Message,也不会摘取这些消息了。请注意,此时只是不会摘取“普通Message”了,如果队列中还设置有“异步Message”,那么还是会摘取已到时的“异步Message”的。

在Android的消息机制里,“普通Message”和“异步Message”也就是这点儿区别啦,也就是说,如果消息列表中根本没有设置“同步分割栏”的话,那么“普通Message”和“异步Message”的处理就没什么大的不同了。
*/

int enqueueSyncBarrier(long when) {
// 插入一个新的同步barrier token
// 我们不需要唤醒queue,因为barrier的目的是暂缓它
synchronized (this) {
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.when = when;
msg.arg1 = token;

Message prev = null;
Message p = mMessages;
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
if (prev != null) { // invariant: p == prev.next
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;
}
}

void removeSyncBarrier(int token) {
// 从queue中移除同步barrier
// 如果queue不再需要用barrier停滞那么唤醒它。
synchronized (this) {
Message prev = null;
Message p = mMessages;
while (p != null && (p.target != null || p.arg1 != token)) {
prev = p;
p = p.next;
}
if (p == null) {
throw new IllegalStateException("The specified message queue synchronization "
+ " barrier token has not been posted or has already been removed.");
}
final boolean needWake;
if (prev != null) {
prev.next = p.next;
needWake = false;
} else {
mMessages = p.next;
needWake = mMessages == null || mMessages.target != null;
}
p.recycle();

// If the loop is quitting then it is already awake.
// We can assume mPtr != 0 when mQuitting is false.
if (needWake && !mQuitting) {
nativeWake(mPtr);
}
}
}

boolean enqueueMessage(Message msg, long when) {
if (msg.isInUse()) {
throw new AndroidRuntimeException(msg + " This message is already in use.");
}
if (msg.target == null) {
throw new AndroidRuntimeException("Message must have a target.");
}

synchronized (this) {
if (mQuitting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread");
return false;
}

msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// 插到第一个位置,如果是阻塞状态唤醒event queue
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// 插到queue中间。通常我们不必唤醒event queue除非有个barrier在queue的开始位置并且the message在queue里是最早的异步message
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}

// We can assume mPtr != 0 because mQuitting is false.
//
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}


boolean hasMessages(Handler h, int what, Object object) {
if (h == null) {
return false;
}

synchronized (this) {
Message p = mMessages;
while (p != null) {
if (p.target == h && p.what == what && (object == null || p.obj == object)) {
return true;
}
p = p.next;
}
return false;
}
}
void removeMessages(Handler h, int what, Object object) {
if (h == null) {
return;
}

synchronized (this) {
Message p = mMessages;

// Remove all messages at front.
while (p != null && p.target == h && p.what == what
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycle();
p = n;
}

// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.what == what
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycle();
p.next = nn;
continue;
}
}
p = n;
}
}
}

Looper

/**
这个类用来给一个线程运行一个message loop.线程默认没有和它们相关联的message loop。创建:在那个准备run the loop的线程中调用prepare,然后调用loop来处理进程message直到这个loop停止。

  • 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();
  • }
  • }
    */
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// sThreadLocal.get() 会返回null,除非我们已经调用了prepare()
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // 由 Looper.class管理

/**
初始化当前线程为一个looper,这个函数给你一个创建引用这个looper的handlers的机会
在真正开始loop之前,请确保调用
*/

public static void prepare() {
prepare(true);//默认是允许退出loop的
}

private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {//确保一个线程只有一个Looper
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}

private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}

/**
初始化当前线程为一个looper,并且让它做为一个应用的主looper. 应用的主looper是被Android环境创建,所以你永远不需要调用这个方法,
*/

public static void prepareMainLooper() {
prepare(false);//主looper是不允许退出的。
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}

/**
返回当前线程相关联的Looper对象,如果调用这个方法的线程没有关联一个Looper返回null
*/

public static Looper myLooper() {
return sThreadLocal.get();
}

/**
* 返回和当前线程相关联的MessageQueue.必须在运行Looper的线程调用,否则抛出空指针异常。
*/

public static MessageQueue myQueue() {
return myLooper().mQueue;
}

/**
返回应用的主looper,这个looper存在于应用的主线程
*/

public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
/**
在这个线程运行message queue。确定调用quit来终止loop
*/

public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;


// 确保这个线程的身份是本地进程的。并且跟踪身份的token值的真实值
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();

for (;;) {
Message msg = queue.next(); // 有可能阻塞
if (msg == null) {
// 没有message表明message queue正在退出
return;
}

// 这必须是个本地变量,防止一个UI事件设置logger.
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}

msg.target.dispatchMessage(msg);

if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}

// 确保这调度过程中,确保线程的身份没有被损坏
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}

msg.recycle();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
提交一个同步的barrier到Looper的message queue
message的处理像平常一样发生直到message queue遇到同步的barrier被提交.当遇到barrier,后来的queue中同步的messages会被暂缓(防止被执行),直到调用remveSyncBarrier释放barrier并在释放的时候指定能够识别同步barrier的token
age的执行直到释放barrier.异步的messages不受影响,继续按通常一样运行。

这次必须和调用removeSyncBarrier配对调用,而且使用相同的token来确保message queue回复正常运行。否则应用有可能会挂起
返回唯一的标示barrier的taken
* @hide
*/

public int postSyncBarrier() {
return mQueue.enqueueSyncBarrier(SystemClock.uptimeMillis());
}


/**
* @hide
*/

public void removeSyncBarrier(int token) {
mQueue.removeSyncBarrier(token);
}

简单来说首先需要Looper.prepare()来初始化当前线程中的Looper,并放置到Looper的静态ThreadLocal中,并初始化一个空的MessageQueue。然后新建一个Handler,在Handler的构造过程中,获取到该线程的Looper和Looper相对应的MessageQueue。然后调用Looper.loop()。这时候从Handler 通过MessageQueue的enqueueMessage提交message,并设置message的target为本Handler。然后在loop()中调用MessageQueue的next()获取到下一个该处理的message,调用message的target来执行最后操作,完毕之后msg被回收。