Looper类是android系统中重要的类,用于处理android线程方面的应用。它的主要作用是初始化MessageQueue类,并且分配消息的处理。Looper类的源码非常简短,可以好好的分析一下源码:
private static final String TAG = "Looper";
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal sThreadLocal = new ThreadLocal();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
volatile boolean mRun;
private Printer mLogging;
在这些成员变量中,最重要的属性分别是sThreadLocal和mQueue,sThreadLocal是ThreadLocal类型的变量,对于这个ThreadLocal类型,正确的理解应该是ThreadLocalVariable,是一个线程本地化的变量,对于这个对象在每个线程中都像是拥有单独的变量一样,这样多个线程之间就不会产生竞争关系。mQueue是一个MessageQueue对象,暂时可以理解是一个阻塞队列,后面再去详细介绍。那么对于非UI线程的线程,使用Looper的第一步都是Looper.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);
mRun = true;
mThread = Thread.currentThread();
}
在这个方法中,我们可以清楚看到Looper设置了sThreadLocal的值和初始化了MessageQueue。接下来调用的是Looper.loop()方法。
public static void loop() {
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();
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
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<
}
// 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.recycle();
}
}
在这个方法中,Looper首先是取出来一个本地化线程下的Looper对象,然后取出该对象中的MessageQueue。然后在for(;;;)语句中循环去取出MessageQueue中的Message对象,然后调用message.target对象的dispatchMessage()方法分发消息,此时的target对象就是一个Handler对象。所以对于Looper类的理解就是:初始化一个MessageQueue和一个本地化变量的Looper,这样handler类就可以通过sendMessage等方法将消息添加到MessageQueue中,并且通过looper方法将消息不断的取出分发到对应的handler去处理。