介绍
looper在消息机制中负责消息循环,实现上来说就是通过不断读取MessageQueue中的消息,有消息就转发给Handler处理,没有就堵塞。通过Looper.prepare可以为当前线程创建Looper,通过Looper.loop开始工作。
prepare实现
public static void prepare() {
prepare(true);
}
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));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
prepare的代码很简单,就是生成了当前线程的Looper,Looper又生成了一个MessageQueue。可以看到,Looper是用一个ThreadLocal保存了新生成的Looper,ThreadLocal是一个线程内部的数据存储类,数据存储之后,只有在指定线程可以获取到存储的数据,保证了每个线程都有且只有一个Looper。接下来看loop是怎么运行循环的。
message执行流程
public static void loop() {
final Looper me = myLooper();
if (me == null) {(1)
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
.......
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {(2)
// No message indicates that the message queue is quitting.
return;
}
.......
try {
msg.target.dispatchMessage(msg);(3)
.......
} finally {
......
}
.......
msg.recycleUnchecked()(4);
}
}
loop方法也很简单,它开启了一个死循环,不断读取MessageQueue的内容,如果读出来的msg为null,就表示MessageQueue停止了,便退出;否则就把msg发给对应Handler(msg.handler),所以Handler的dispatchMessage方法(事实上也就是handleMessage方法),是运行在Looper指定的线程,也就是调用Looper.prepare的代码所在的线程里的。