1.消息处理遵循 生产者消费者模式
Handler既是生成者,又是消费者
Message是产品
MessageQueue充当阻塞队列,内部使用Link来实现,用msg.when来实现队列内msg的排序
Looper 使用MsgQueue
Msg
what,args,data代表msg可以携带变量
flags用来标识是否在使用(FLAG_IN_USE),如果在使用,将不会放入Queue中
是否是同步(FLAG_ASYNCHRONOUS),异步的消息将不会被阻塞msg阻塞
when标识msg执行时间
target 执行msg的handler
Callback 它可以携带的runnable,优先于handlemsg执行
next link结构中代表下一个节点的msg
实现了Parcelable接口,可以跨进程通信
其他就是构造方法和getter,setter以及toString的覆盖
Handler
发送消息 send方法/post(Runnable)
删除消息remove方法
构造消息obtain方法,拿到Msg静态变量的msg
处理消息 dispatch方法,内部类Callback,子类覆盖callback的handlemsg真正执行消息
构造方法,调用Looper.myLooper获取当前线程的对应looper
Looper
构造方法为私有,
使用工厂方法来获取looper实例
利用ThreadLocal保存每一条线程一个实例
委托mQueue来处理消息
prepare用来在 ThreadLocal添加set
myLooper取得当前线程对应的looper
默认存储了app的主线程对应的looper--mainlooper,可以通过getmainLooper获取
loop方法 开启一个空for语句 调用msgQueue.next来获取msg,调用msg对应的handler.dispathmsg来处理消息,处理完以后,调用msg.recycle来回收
在线程中使用handler必须要调用loop方法触发消息派发机制
HandlerThread
封装了一个looper 的线程
在 run方法内将线程与looper绑定(set到ThreadLocal中,)然后执行loop方法触发循环
MsgQueue
looper委托它,真正执行msg消息派发机制
整个是一个link机制,链表表头为mMessages
添加msg,enqueueMessage方法
1.判断是否有效
2.判断插入新msg的执行时间 when,插入到link的对应位置
3.判断执行唤醒
删除msg-removeMessages(Handler h, int what, Object object)
将所有相同h,what,object的msg中从link中移除同时回收recycle
循环调度next方法
for (;;) {if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
native方法实现时间的等待
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
//barrier型的msg只能阻塞asynchronous型的msg
if (msg != null && msg.target == null) {// Stalled by a barrier. Find the next asynchronous message in the queue.
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
当前时间与msg执行时间比较,获取需要等待的时间,然后用native方法等待
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);} else {
// Got a message.
正常执行流,获取到下一个msg
mBlocked = false;if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (false) Log.v("MessageQueue", "Returning message: " + msg);
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
IdleHandler用来在空闲的时候可以执行一些不重要的任务的回调
SyncBarrierMsg用来添加空的msg,这些msg只用来当做时间的延时