首先打开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();
}
}
这是一个在子线程中创建Handler的例子,我们就以这个例子来讲解。
Looper.prepare();
在子线程中,在创建Handler之前先执行了Looper.prepare(),我们先来看下Looper.prepare()的代码:
static final ThreadLocal sThreadLocal = new ThreadLocal();
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");
}
//创建Looper对象,并把Looper存入ThreadLocalMap
sThreadLocal.set(new Looper(quitAllowed));
}
//ThreadLocal的set()方法
public void set(T value) {
//获取当前线程
Thread t = Thread.currentThread();
//获取当前线程的ThreadLocalMap
ThreadLocalMap map = getMap(t);
//把ThreadLocal为key,Looper为value存入ThreadLocalMap
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
//Looper的构造方法,创建了一个MessageQueue
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Looper.prepare()的作用就是创建一个Looper和一个MessageQueue对象,Looper.prepare()只能调用一次,再次调用就会抛throw new RuntimeException("Only one Looper may be created per thread")异常,所以每一个线程对应唯一的一个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());
}
}
//获取当前线程的Looper对象(Looper.myLooper()的源码在下面)
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//获取当前线程的Looper对应的MessageQueue
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
从上面可以看出Handler的构造方法,其实就是获取当前线程的Looper和MessageQueue,我们通过Handler的sendMessage发送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) {
//把当前Handler对象赋值给msg.target
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//把Message放到MessageQueue中
return queue.enqueueMessage(msg, uptimeMillis);
}
Looper.myLooper()
Looper.myLooper()先获取当前线程,再获取当前线程的ThreadLocalMap,然后从ThreadLocalMap中获取先前存入的Looper。
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
//ThreadLocal的get()方法
public T get() {
//获取当前线程
Thread t = Thread.currentThread();
//获取当前线程的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()
循环从MessageQueue中取出Message,通过msg.target就是发送Message的Handler,调用Handler的dispatchMessage(msg)分发消息。
public static void loop() {
//获取当前线程的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();
//循环从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就是发送Message的Handler,dispatchMessage(msg)分发消息
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交给对应的方法处理,这里是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) {
}
总结
Looper的prepare()方法创建了一个Looper对象,并且保证每个线程最多只有一个Looper对象。在主线程中,系统已经初始化了一个Looper对象,因此可以直接创建Handler,在子线程必须调用Looper.prepare()创建一个Looper对象,并调用Looper.loop()启动它。
Handler的构造方法,会获取当前线程的的Looper,进而获得关联的MessageQueue,Handler的sendMessage会给msg.target赋值为自身,然后把Message存入MessageQueue。
Looper不断的从MessageQueue中取出Message,通过msg.target获取对应的Handler,调用Handler的dispatchMessage(msg)把Message交给对应的方法处理。