定义
Looper和MessageQueue的消息就像水泵和井(里边装的是水)的关系一样,我们有了消息(水),但是为了把水从井中抽取出来(循环起来),我们得有一个水泵作为动力,这个动力就是Looper。
如果我们在一个线程中调用Looper.prepare()...Looper.loop()
,那么你的线程就成功升级为了一个Looper线程,这意味着你的线程有了一个消息泵(Looper)和一个消息队列(MessageQueue),此时你就可以调用Handler来进行线程间的通信了。
理解
我们应用的UI线程也就是主线程,在应用启动的时候,系统会自动初始化一个Looper,也就是说,我们的UI线程默认是Looper线程。这也就是为什么主线程中直接调用Handler没什么事,但是再子线程中创建Handler需要哦手动调用Looper.prepare()...Looper.loop()
的和原因。
Android消息机制中,Looper处于核心地位,它类似于一个消息泵,不断从MessageQueue中读取数据,然后分发给Handler去处理。
二、Looper源码阅读:
上述子线程中调用了Looper.prepare()和Looper.loop()到底做了什么事情?
1、先看prepare()方法:
public static void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
prepare是一个静态方法,那就意味着可以直接通过类名访问,这个方法只做了一件事,就是创建一个Looper对象,把这个对象放到sThreadLocal中。在创建之前会判断sThreadLocal是否为空,即保证当前只有一个Looper对象。
2、loop方法:
public static void loop() {
while (true) {
Message msg = queue.next(); // might block
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
msg.target.dispatchMessage(msg);
msg.recycle();
}
}
上述方法只截取了部分,可见也是一个静态方法,做的事情也很简单,很单调:不停的检查MessageQueue,拿到Message,根据Message的target将消息分发给Handler,分发完成之后回收消息;
总之,handler的线程就是提供下handler这个实例变量而已,而真正循环处理消息的线程是looper所在的线程了。
这就是Handler的Loop消息泵机制,一篇简单的解析。你是否能理解呢?更多有关framework以及它的Handler学习,可点击前往获取《Framework》和《Handler》学习手册。由一位腾讯Android架构师整理合成,需要可上方粗体字获取!
总结:
Thread和Looper是一一对应关系。
Thread和MessageQueue也是是一一对应关系。
俗一点说:一个Thread只有一个Looper对象,一个MessageQueue对象;
Looper分发消息是阻塞式的(might block),即一个消息分发完成之后才会处理下一个消息。
“Looper就是一个While循环,不停的从MessageQueue读取Message并分发给Handler处理,而调用Looper.loop()启动了循环”。