内容简述
类似Binder机制,MessageQueue、Looper也有底层的C++实现,涉及文件管道和驱动等。
以下仅从Java层的Looper、Handler和MessageQueue等相关类型的源码来分析线程消息处理的机制。
MessageQueue的创建
Looper用来创建和启动消息队列。
Looper对象和线程绑定是通过ThreadLocal实现的。
它提供了各种getter方便获取线程关联的MessageQueue和Looper对象。
Looper.prepare();
Looper.prepareMainLooper();
线程通过执行Looper.prepare()来创建关联的MessageQueue。
主线程则调用prepareMainLooper()来创建主线程关联的Looper,方便其它线程向主线程发消息。
Looper.prepare()
它新建了Looper对象,以ThreadLocal存储它,所以和当前线程绑定。
构造函数中创建了消息队列:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
MessageQueue的创建
// MessageQueue.java
private long mPtr;
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
nativeInit()调用C++代码创建底层的C++MessageQueue对象。
有了MessageQueue对象以后,接着需要开启消息循环,使用关联的Handler来发送、处理消息了。
消息循环
MessageQueue有点像一个阻塞队列,它提供MessageQueue.next()用来从队列中取出一个Message对象。
若没有消息则调用会阻塞。
Looper.loop()
Looper.loop()用来开启对MessageQueue的取消息操作的无限循环。
public static void loop() {
final Looper me = myLooper();
...
final MessageQueue queue = me.mQueue;
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
msg.target.dispatchMessage(msg);
...
msg.recycleUnchecked();
}
}
可以看到,loop()的操作就是无限从queue中调用next()获取一个新Message对象,然后执行dispatchMessage来处理它。
MessageQueue.next()
nativePollOnce()用来检查队列中是否有新的消息。
参数nextPollTimeoutMillis表示在暂无消息时此次检查过程需要休眠的时间:
- 等于-1:表示无限等待,直到被其它线程唤醒。
- 等于 0:继续循环检查队列。
- 大于 0:以nextPollTimeoutMillis的毫米数等待。
使用for (;