>[图解法结合源码理解、记忆Handler、Looper、MessageQueue之间的关系]
看了不少关于Handler、Looper、MessageQueue之间关系的文章。感觉挺枯燥的,上来就是一团代码,看着心烦。
后来我捋了捋,画了个图。先看图,我们再来谈他们间的关系:
在这个图中,我做了个类比:(很重要,多看几遍)
MessageQueue,流水线上的"履带";
Looper,履带的"驱动轮";
Handler,流水线上的"工人";
Message,流水线上的"包裹"。
现在让我们来解释这三者间的工作关系,首先,我们要明确一个基本法:
一个Thread只能有且只能一个Looper。一个Looper只能对应一个Message。一个Looper和MessageQueue的绑定体可以对应多个Handler。(参考上图)
1.Looper与MessageQueue
刚刚说了一个Thread只能有一个Looper。为什么只能有一个呢?让我们去看它的一个方法Looper.prepare()方法的源码:
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(true));
}
第二行,如果当前线程已有一个Looper,那么将直接抛出异常。
然后我们再来说说一个线程一般要怎么创建一个Looper,例子A:(下面会拿这个例子讲解)
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// 你的方法
}
};
}
Looper.loop();
}
首先,一个线程先Looper.prepare(),创建一个Looper,在这个prepare()方法中,回头看一眼第一段里的代码,它会在 return 中new 一个(Looper(true));其实,就是下面的代码:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread(); //绑定当前线程
}
注意第二行,它创建并绑定了一个MessageQueue,做个类比,就是给Looper这个驱动轮套上了它的履带MessageQueue,由于Looper在当前线程唯一,则其应为一一对应关系。
现在驱动轮有了,履带有了,要让这个流水线动起来,显然,还需要另外一个操作。
没错