Android Handler机制源码浅析(下)

3.MessageQueue

Android Handler机制源码浅析(上):https://blog.csdn.net/XCF95319605/article/details/81080939

MessageQueue即消息队列,主要的作用是存放消息,MessageQueue最重要的操作就是插入消息和读取消息(移除消息),从handler的源码分析中我们已经知道,MessageQueue是通过他的enqueueMessage方法向队列中插入一条消息,在Looper中又是通过MessageQueue的next方法来获取到消息,所以MessageQueue是通过enqueueMessage和next来插入和读取消息的(注意:消息队列的底层实现是单链表并非队列)

(1) 首先我们来分析一下enqueueMessage的源码实现:

boolean enqueueMessage(Message msg, long when) {
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        …
        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w(TAG, e.getMessage(), e);
                msg.recycle();
                return false;
            }

            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 { 
                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;
    }

从源码可以清楚的看见,enqueueMessage就是简单的单链表的插入操作,前面做了一些条件判断和线程锁操作,红色部分就是将消息添加到单链表的简单操作。

(2) 接下来看一下next的源码实现

Message next() {
        …
        int pendingIdleHandlerCount = -1; // -1 only during first iteration
        int nextPollTimeoutMillis = 0;
        for (;;) {
            if (nextPollTimeoutMillis != 0) {
                Binder.flushPendingCommands();
            }

            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;
                if (msg != null && msg.target == null) {
                do {
                        prevMsg = msg;
                        msg = msg.next;
                    } while (msg != null && !msg.isAsynchronous());
                }
                if (msg != null) {
                  if (now < msg.when) {
                    nextPollTimeoutMillis = (int) Math.min(
msg.when - now, Integer.MAX_VALUE);
                   } else {
                        // Got a message.
                        mBlocked = false;
                        if (prevMsg != null) {
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);
                        msg.markInUse();
                        return msg;
                    }
                } else {
                    // No more messages.
                    nextPollTimeoutMillis = -1;
                }
                // Process the quit message now that all pending
// messages have been handled.
                if (mQuitting) {
                    dispose();
                    return null;
                }
               …
            }
           …
        }
    }

从源码很容易就看出来,next内部有一个for(;;)死循环,如果MessageQueue中没有消息,next会循环等待,若有消息,则会将消息返回,并且将消息从MessageQueue中移除。

至此,整个Handler机制的分析就全部结束了,最后,用一张图来总结一下Handler消息的传递顺序及其调用的关系:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值