- Android-Handler源码解析-Handler
- Handler、Looper、MessageQueue源码解析—
- Handler、Looper、MessageQueue源码解析—
- Handler、Looper、MessageQueue源码解析—
- Handler、Looper、MessageQueue源码解析—
- Android进阶:三、这一次,我们用最详细的方式解析Andro
- Android进阶:三、这一次,我们用最详细的方式解析Andro
- Android-Handler源码解析-MessageQueue
- Android-Handler源码解析-Message
- Android-Handler源码解析-Looper
关联类
Handler Message MessageQueue Looper
1、handler 的构造方法
Handler(Looper looper, Callback callback, boolean async)
looper :必须的
callback : 处理handlemsg的
async : ??? defalut = false
2、handler 构造方法中会获取 looper 和 looper.queue (messageQueue)
3、sendMessage 流程
1、所有的sendMessage 都是走的 sendMessageDelayed 方法 最后走到 sendMessageAtTime 方法
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
// 里面只有两行 代码, 主要是 enqueueMessage 方法
return enqueueMessage(queue, msg, uptimeMillis);
}
2、enqueueMessage 方法其实走的是 messageQueue中的方法 ,该方法是synchronized 同步锁
// 注意这里,msg.target = this // 把msg和调用他的handler绑定了
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
// 这个参数暂时不研究
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
3、在MessageQueue的enqueueMessage 方法里面 分析 可以知道
message 是链表形式, 按照时间进行排序的 根据时间 插入到对应的位置
Message prev;
for (;;) {
prev = p; // P 是当前message链的头
p = p.next;
if (p == null || when < p.when) { // when 是新插入进来的message的时间
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // 按照时间大从小到大的顺序,把 新的msg插入到链表里面
prev.next = msg;
// 下面就是 判断messagequeue是否在被阻塞或者等待, 使用nativeWake 唤醒
4、MessageQueue中removeMessages方法是单链表的删除操作
5、handler.postDelayed()方法 实际上是 sendmessage方法,其中传入的 runnable,作为了 message的callback方法—————— 所以 我们messge 的时候,不要new了。直接handler.obtainMessage()
public final boolean postDelayed(Runnable r, Object token, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r, token), delayMillis);
}
private static Message getPostMessage(Runnable r, Object token) {
Message m = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
6、真正的轮寻,查找message 没有在 messageQueue里面,也没有在 handler里面,更没有在 message里面
Looper.prepare() 只是在 sThreadLocal.set(new Looper(quitAllowed)); 在当前线程里面设置一个 looper
main线程会自动存在
looper.loop() 方法就牛了
for (;;) {
Message msg = queue.next(); // might block
try { // 主要执行次方法,
msg.target.dispatchMessage(msg);
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
msg.recycleUnchecked();
}
// 在 messageQueue 中 通过循环判断 msg的when是不是 》=now
是就获得message
在sendMessage的时候 回调用 nativeWake() 唤醒轮训的操作
网友评论