Handler进阶之sendMessage
sendMessage(Message msg);//立刻发送消息 sendMessageAtTime(Message msg, long atTime);//在某个时间点发送消息 sendMessageDelayed(Message msg, long delayedTime);//在当前时间点延迟一段时间发送消息
以上是三个Handler发送消息的方法,区别在于发送的时间点不一致,但其实三个方法在最终都是执行Handler内的同一个方法,只是在参数上稍有区别:
public final boolean sendMessageDelayed(Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } sendMessage(Message msg); //对应 sendMessageDelayed(msg, 0); sendMessageAtTime(Message msg, long atTime); //对应 sendMessageDelayed(msg, atTime) sendMessageDelayed(Message msg, long delayedTime); //对应 sendMessageDelayed(msg, SystemClock.uptimeMillis() + delayedTime)
Handler消息机制原理全方面解读
此处直接看Message放入MessageQueue的过程:
boolean enqueueMessage(Message msg, long when) { ...//代码较多,省去了部分抛出异常的代码 synchronized (this) { ... msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; 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; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
重点就在if-else这里,将它们一个一个拆开来看:
if (p == null || when == 0 || when < p.when) {//p是当前MessageQueue队首Message // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; }
needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; 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;
之所以写这篇文章主要是为了解答两个问题。
- sendMessageDelayed是如何实现延时发送消息的?
- sendMessageDelayed是通过阻塞来达到了延时发送消息的结果,那么会不会阻塞新添加的Message?
总结:
- Handler在发送消息的时候,MessageQueue里的消息是按照发送时间点从小到大排列的,
如果最近的Message未到达发送的时间则阻塞。 - 新加入的数据会根据时间点的大小判断需要插入的位置,同时还需要判断是否需要唤醒线程去发送当前的队首的消息。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232076.html原文链接:https://javaforall.net
