android消息机制浅析
1.简单描述Android 消息机制
1.发送一个消息Handler.sendMessage->Handler.enqueueMessage->MessageQueue.enqueueMessage
2.发送的消息会保存到MessageQueue中的mMessages里面,它是一个单链表,上面的enqueueMessage会根据时间的先后顺序进行存储
3.主线程的ActivityThread.main会执行Looper.prepareMainLooper()和Looper.loop()启动一个死循环,在循环里面检测消息队列(MessageQueue)的消息(queue.next),没有消息就会调用nativePollOnce阻塞线程,释放cpu资源,线程休眠,有消息取出消息,调用msg.target.dispatchMessage(msg)回调Handler里面的这个方法,这个方法里面处理消息
2.简单描述消息机制的阻塞、唤醒、延时加入消息队列
1.消息的阻塞在MessageQueue的next方法,阻塞调用的方法是nativePollOnce(ptr, nextPollTimeoutMillis),nextPollTimeoutMillis是阻塞时间,为-1时候,一直阻塞,直到被唤醒,为0不需要阻塞,大于0为阻塞的时间,时间到了,唤醒线程。
2.消息的唤醒在MessageQueue的enqueueMessage方法,唤醒的方法是nativeWake(),底层是epoll机制,通过往pipe管道写端写入数据来唤醒主线程工作,当线程唤醒nativePollOnce就不会阻塞,继续往后执行,取消息,以及分发消息
3.消息延时加入队列
发送延时消息,延时的消息为当前时间加上需要延时的时间,然后保存在Message的when变量中,消息入队在enqueueMessage方法中,里面会根据时间的先后顺序将Message插入到mMessages单链表中,时间到了,会取出消息,然后处理消息。
```java
//消息延时入队代码块
//当前mMessage中没有消息,并且时间为0,并且小于p中消息的时间,直接将消息存放给mMessage
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
//mMessage中有消息,就遍历单链表
Message prev;
for (;;) {
prev = p;
p = p.next;
//消息时间小于当前遍历到的消息时间,就break
if (p == null || when < p.when) {
break;
}
...
}
//将遍历到的消息,插入到msg的next里面,然后将msg赋给prev.next,即消息的插入
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}