原理图
Message
int what(标识ID)
int arg1 保存int数据
int arg2 保存int数据
Object obj 保存任意数据
long when 记录应该处理的时间
Handler target 每一个Message都保存一个用来处理此Message的Handler(发送消息的Handler)
Runnable callback 用来处理消息的回调器(一般不用)
Message next 用来指向下一个Message(形成链表)
Message sPool 用来缓存处理过的Message对象 以便复用
Handler
主要用来发送消息 处理消息 移除消息
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
最终都是调用 sendMessageDelayed
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
从此方法获取消息队列
sendMessageAtTime(Message msg, long uptimeMillis)
调用消息队列将消息添加到消息队列
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
调用消息队列将消息移除队列
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
分发消息
public void dispatchMessage(Message msg) {
if (msg.callback != null) { //如果消息可以自己处理,让消息自己处理
handleCallback(msg);
} else {
if (mCallback != null){ //如果Handler对象中有回调监听器,调用回调器来处理消息
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg); //让Handler的handleMessage()来处理
}
}
MessageQueue
存储消息的以message的when排序优先级队列
将Message添加到队列中
enqueueMessage(Message msg, long when)
从小到大按when排序队列链表
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
取出一个合适的Message对象,可能不会立即返回
next()
本地方法,可能会导致处于等待状态,但不会阻塞主线程
nativePollOnce(ptr, nextPollTimeoutMillis);
调用Handler去分发消息
msg.target.dispatchMessage(msg);
Looper
从MessageQueue中获取当前需要处理的消息,并交给Handler处理
得到Looper对象
final Looper me = myLooper();
得到消息队列
final MessageQueue queue = me.mQueue;
无线循环没有break
for (;;) {
Message msg = queue.next(); // might block
调用Handler去分发并处理消息
msg.target.dispatchMessage(msg);
回收利用Message
msg.recycleUnchecked();
}