Android 异步消息机制 Handler、Message、Looper
此文为鸿洋博客阅读笔记,配合原文食用口味更佳。
Android 异步消息处理机制 让你深入理解 Looper、Handler、Message 三者关系 - CSDN 博客
导图

过程分析
Looper
Looper.perpare()
Looper.perpare()方法创建Looper对象(同时创建MessageQueue对象),并与当前线程关联保存在sThreadLocal中。
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(true));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread();
}Looper.loop()
Looper.loop()方法获取保存的Looper对象并由此获取到MessageQueue对象。
通过for循环,不停的通过mQueue获取到msg,并调用msg.target.dispatchMessage(msg)执行 msg 对应的处理方法。
最后通过msg.recycle()回收使用完的 msg。
public static void loop() {
final Looper me = myLooper();
...
final MessageQueue queue = me.mQueue;
...
for (;;) {
Message msg = queue.next(); // might block
...
msg.target.dispatchMessage(msg);
...
msg.recycle();
}
}Looper.myLooper()
myLooper()内部调用sThreadLocal获取已有的Looper对象
public static Looper myLooper() {
return sThreadLocal.get();
}Android 的 Activity 默认在 UI 线程调用了 Looper 的prepare()和loop()方法
Handler
handler.sendMessage()
Handler 构造方法会获取到mLooper和mQueue以及mCallback
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
mCallback = callback; // Handler() 中此值为 nullsendMessage()方法最终会调用sendMessageAtTime()方法,在其内部调用enqueueMessage()方法,将 handler 赋予 msg.target,并将 msg 压入 mQueue 中
//enqueueMessage 方法
msg.target = this;
queue.enqueueMessage(msg, uptimeMillis);//将 handler 发送的 msg 压入到当前线程的 Looper 持有的 MessageQueue 中handler.dispatchMessage()
Handler 的dispatchMessage()方法会在Looper.loop()中被调用
public void dispatchMessage(Message msg) {
if (msg.callback != null) { //msg 自带的回调方法
handleCallback(msg);
} else {
if (mCallback != null) { //handler 指定的回调方法
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg); //handler 的 handleMessage() 方法
}
}其中执行顺序是:msg.callback > mCallback > handleMessage()
handler.post()
handler.post(new Runnable())调用了getPostMessage(r)方法将 r 赋予 msg.callback
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}最后也是在sendMessageDelayed方法中调用sendMessageAtTime()方法将 msg 压入 MessageQueue 中
public final boolean sendMessageDelayed(Message msg, long delayMillis) {
...
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}msg 的获取
Message.obtain();复用 MessageMessage 池中已有的对象,避免出现分配内存 推荐new Message();
总结
Looper在**perfare()**方法中创建Looper及MessageQueue对象并保存在sThreadLocal中,
在**loop()**方法中通过myLooper()从sThreadLocal中取出mLooper,并由此获得mQueue,在 for 循环中通过mQueue.next()获取msg,用msg.target.dispatchMessage()方法回调handler中的msg处理方法。
Handler在**构造函数**中通过Looper.myLooper()获取到当前线程的Looper和MessageQueue;
**sendMessage()**方法最终通过sendMessageAtTime()调用enqueueMessage()方法将msg压入到MessageQueue中。
至此将Looper 和 Handler 通过 MessageQueue 联系在一起,并共同参与处理 Message。
此外**handler.post(runnable)也是通过在post()**内部调用getPostMessage()方法将runnable赋予msg.callback,并在post()中通过sendMessageDelayed()方法调用sendMessageAtTime()方法将msg压入MessageQueue中
