Handler、Looper、MessageQueue、Message之间的关系
一般创建一个Handler,会得到所在线程的Looper。如果所在线程没有Looper,则会出现运行时异常。
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());
}
}
mLooper = Looper.myLooper(); //得到当前线程中的Looper
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue; //当前Looper管理的MessageQueue
mCallback = callback;
mAsynchronous = async;
}
主线程(UI线程)中都有一个Looper,在ActivityThread的main函数中:
public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper(); //创建Looper
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop(); //循环
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Looper用于管理消息MessageQueue,在Looper中,有一个MessageQueue:
final MessageQueue mQueue;
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
MessageQueue消息队列,维护一系列消息的先进先出。主要有消息进队列enqueueMessage,删除消息removeMessages,下一条消息next等。
Message即使发送的一条一条消息。
Handler通过sendMessage和post等方法,将一条消息放入到消息队列中,
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) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
然后消息进入消息队列,消息队列中的消息会通过Looper循环取出分发:
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); //分发消息,通过对应消息的Handler来分发消息
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.recycle();
}
}
Handler target;
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg); //是Runnable对象
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
message.callback.run(); //跑Runnable对象的run方法
}
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) { //跑自己写的方法
}
这样消息就会在相应的Handler中进行相应的处理了。
这样也就很好理解为什么可以在子线程中通过主线程的Handler来发送一条消息,最后被主线程的Handler中HandleMessage处理了。
因为最终都是这样:哪个Handler发的消息,就由自己来处理,而handler在哪个线程中,则使用当前线程的Looper,如果没有,可以自己创建一个。
Enjoy~今天(2015/10/13)看《深入理解Android卷I》,上面有两句话来总结它们之间的关系,看到的时候一下就觉得都顺了。
分享出来~
(1)Looper中有一个消息队列MessageQueue,里面存储的是一个个待处理的消息Message;
(2)Message中有一个Handler,这个Handler是用来处理Message的。