今天我读了一些关于Handler & Looper如何协同工作的博客和源代码。为什么主线程的Looper.loop()不会阻塞UI线程?
根据我所了解的情况,我们可以通过使用ThreadLocal
魔法在每个线程上只有一个Looper。通常Handler是在主线程中启动的,否则您必须在单独的线程上手动启动或说出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();
}
}
真正困惑我的是主线程中的loop()
。正如我在Looper的源代码中读到的那样。处理消息队列,然后为回调处理消息发送消息是一个无限循环。
根据这个https://stackoverflow.com/a/5193981/2290191,Handler和它的Looper运行在同一个线程中。
如果主线程上有一个无限循环,是不是会阻塞整个UI系统?
我知道我必须如此傻才能错过什么。但有人透露这背后的秘密是可爱的。
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("<<<<< 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();
}
}
我不认为你仔细阅读我的问题。我的意思是,如果主线程上有for(;;){}'循环,那么如何发送消息来绘制UI? –
我做过了,我不认为你理解我的答案。其中一条消息引起了抽签。平局是发送给该活套的特殊信息。 –
或者换一种说法 - 你认为主线程实际上是Looper处理消息并调用你的代码来响应它。这是一种称为事件循环或消息循环的技术,这在事件驱动编程中很常见。以下是Android的http://mattias.niklewski.com/2012/09/android_event_loop.html –