两个问题
handler发送Message到哪里,如何回调并处理Message
子线程中使用Handler
在子线程中使用Handler必须先调用Looper.prepare(),否则有RuntimeException抛出
Looper.prepare();
new Handler().post(new Runnable() {
@Override
public void run() {
//run方法运行在子线程中
}
});
Looper.loop();
接下来我们逐步分解每一步做了什么
Looper.prepare()
我们先看看Looper.prepare()的部分源码,看它准备了什么
Looper.java
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static void prepare(boolean quitAllowed) {
//为当前线程生成Looper对象并维护在sThreadLocal中
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
//消息队列在此时生成
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
最重要的就是生成了MessageQueue,每个线程仅有一个
new Handler()
在new Handler()时,获取了当前线程的MessageQueue
Handler.java
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async){
//当前线程的Looper
mLooper = Looper.myLooper();
//如果该线程没有调用过Looper.prepare,异常就在这里抛出
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//发送message将使用这个mQueue
mQueue = mLooper.mQueue;
}
Looper.java
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
handler.post与sendMessage
handler.post或sendMessage系列方法最终都调用enqueueMessage,post方法多了一步将Runnable封装在Message中,以下是post涉及的源码,sendMessage大同小异
Handler.java
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
//注意:callback是我们传入的Runnable对象
m.callback = r;
return m;
}
public final boolean sendMessageDelayed(Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
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就是当前handler
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
Looper.loop()
以下是Looper.loop()的部分源码,无限循环取Message
Looper.java
public static void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
//下面无限for循环会阻塞当前线程
for (;;) {
Message msg = queue.next(); // might block
//消息由target处理,也就是发送该消息的handler
msg.target.dispatchMessage(msg);
}
}
以下是handler.dispatchMessage涉及的源码
Handler.java
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
message.callback.run();
}
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
我们会发现处理消息有3种方式,每次只会选择一种,并且有优先级。
message.callback.run() > mCallback.handleMessage(msg) > handleMessage(Message msg)
总结
我们完整地梳理整个流程
Looper.prepare();//生成MessageQueue
//new Handler() 获得当前线程的MessageQueue
//post()将Message发送至MessageQueue
new Handler().post(new Runnable() {
@Override
public void run() {
//run方法运行在子线程中
}
});
//无限循环取Message,并交由发送的Handler处理
Looper.loop();