首先打開Looper類裁僧,可以看到頭部的說明中有一個小例子,如下:
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();
}
}
這是一個在子線程中創(chuàng)建Handler的例子慕购,我們就以這個例子來講解聊疲。
Looper.prepare();
在子線程中,在創(chuàng)建Handler之前先執(zhí)行了Looper.prepare()沪悲,我們先來看下Looper.prepare()的代碼:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
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");
}
//創(chuàng)建Looper對象获洲,并把Looper存入ThreadLocalMap
sThreadLocal.set(new Looper(quitAllowed));
}
//ThreadLocal的set()方法
public void set(T value) {
//獲取當(dāng)前線程
Thread t = Thread.currentThread();
//獲取當(dāng)前線程的ThreadLocalMap
ThreadLocalMap map = getMap(t);
//把ThreadLocal為key,Looper為value存入ThreadLocalMap
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
//Looper的構(gòu)造方法殿如,創(chuàng)建了一個MessageQueue
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Looper.prepare()的作用就是創(chuàng)建一個Looper和一個MessageQueue對象贡珊,Looper.prepare()只能調(diào)用一次,再次調(diào)用就會拋throw new RuntimeException("Only one Looper may be created per thread")異常涉馁,所以每一個線程對應(yīng)唯一的一個Looper和一個MessageQueue门岔。
new Handler()
public Handler() {
this(null, false);
}
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());
}
}
//獲取當(dāng)前線程的Looper對象(Looper.myLooper()的源碼在下面)
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//獲取當(dāng)前線程的Looper對應(yīng)的MessageQueue
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
從上面可以看出Handler的構(gòu)造方法,其實就是獲取當(dāng)前線程的Looper和MessageQueue烤送,我們通過Handler的sendMessage發(fā)送Message寒随,都是把Message放到MessageQueue中。
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);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//把當(dāng)前Handler對象賦值給msg.target
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//把Message放到MessageQueue中
return queue.enqueueMessage(msg, uptimeMillis);
}
Looper.myLooper()
Looper.myLooper()先獲取當(dāng)前線程帮坚,再獲取當(dāng)前線程的ThreadLocalMap妻往,然后從ThreadLocalMap中獲取先前存入的Looper。
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
//ThreadLocal的get()方法
public T get() {
//獲取當(dāng)前線程
Thread t = Thread.currentThread();
//獲取當(dāng)前線程的ThreadLocalMap
ThreadLocalMap map = getMap(t);
if (map != null) {
//以ThreadLocal為key從ThreadLocalMap取出保存的Looper
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
Looper.loop()
循環(huán)從MessageQueue中取出Message试和,通過msg.target就是發(fā)送Message的Handler讯泣,調(diào)用Handler的dispatchMessage(msg)分發(fā)消息。
public static void loop() {
//獲取當(dāng)前線程的Looper對象
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;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
//循環(huán)從MessageQueue中取出Message
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
final Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
final long traceTag = me.mTraceTag;
if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
}
try {
//msg.target就是發(fā)送Message的Handler灰署,dispatchMessage(msg)分發(fā)消息
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
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.recycleUnchecked();
}
}
msg.target.dispatchMessage(msg)
Handler的dispatchMessage(msg)把Message交給對應(yīng)的方法處理判帮,這里是handleMessage(msg)局嘁。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
public void handleMessage(Message msg) {
}
總結(jié)
Looper的prepare()方法創(chuàng)建了一個Looper對象,并且保證每個線程最多只有一個Looper對象晦墙。在主線程中悦昵,系統(tǒng)已經(jīng)初始化了一個Looper對象,因此可以直接創(chuàng)建Handler晌畅,在子線程必須調(diào)用Looper.prepare()創(chuàng)建一個Looper對象但指,并調(diào)用Looper.loop()啟動它。
Handler的構(gòu)造方法抗楔,會獲取當(dāng)前線程的的Looper棋凳,進而獲得關(guān)聯(lián)的MessageQueue,Handler的sendMessage會給msg.target賦值為自身连躏,然后把Message存入MessageQueue剩岳。
Looper不斷的從MessageQueue中取出Message,通過msg.target獲取對應(yīng)的Handler入热,調(diào)用Handler的dispatchMessage(msg)把Message交給對應(yīng)的方法處理拍棕。