Android 使用Handler跨线程通信原理:每一个线程都已一MessageQueen,一个Looper,Looper不断从MessageQueen中读取Message,交给Handler处理;当然Message也是通过Handler放入MessageQueen中的,即Handler用来发送Message和处理Message。
MessageQueen是由Looper对象创建的,在Looper对象创建时,会和创建Looper的线程关联到一块,所以Thread就有了一个MessageQueen;
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Handler创建时会和改线程的Looper绑定到一起,如果在Handler创建时Looper还未创建,就会报异常。
public Handler(Callback callback, boolean async) {
……
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
Hander发送Message时,把自己设置给Message的target属性,所以在Looper在loop()方法从MessageQueen取出Message,调用message.target.dispathMessage()方法来处理Message。
Handler的sendMessage()方法会调用下面的方法,并指定msg.targe=this,即把Handler指给Message:
//Handler.class
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
Looper.loop()方法源码(API25):
public static void loop() {
……
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
……
try {
//即调用Handler的dispatchMessage(msg)方法
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
……
msg.recycleUnchecked();
}
}
关于loop方法会block的说明:
https://www.zhihu.com/question/34652589/answer/90344494
网友评论