Android 消息机制

本文详细解析了Android消息机制,包括Handler、MessageQueue和Looper的工作原理。Handler用于发送和处理消息,MessageQueue作为消息队列以单链表存储消息,Looper负责循环取出消息并分发。文中还探讨了消息插入、出队流程,以及Looper如何创建和启动消息循环。此外,文章还分析了Handler内存泄漏问题及解决方案,强调了消息执行时间的非精确性,以及Looper的死循环特性。
摘要由CSDN通过智能技术生成

一 概述    

Android消息机制主要指Handler的运行机制,主要包括上层的Handler接口以及下层的MessageQueue和Looper。

  • Handler :  消息处理。通常我们需要继承并实现handleMessage方法或者设置一个Callback。
  • MessageQueue: 消息队列。用于存储消息。
  • Looper: 消息循环。无限循环从消息队列中查找消息。

三者的关系如图:

二 MessageQueue工作原理

MessageQueue负责存储和读取消息,虽然MessageQueue名字叫消息队列,但是实际内部是用一个单链表结构来维护消息列表的。

消息队列存储的消息指的是Message的实例。在分析MessageQueue工作原理前先了解一下Message的一些重要参数。

  • msg.target  代表发送这个Message的Handler实例
  • msg.when  代表执行这个Message的时间
  • msg.isInUse()和msg.markInUse() 判断当前Message是否正在使用和设置使用状态
  • msg.next 下一个需要执行的Message对象
  • msg.callback 一个Runnable对象,通过Handler.post方法设置。

MessageQueue插入操作对应的方法是enqueueMessage方法

    boolean enqueueMessage(Message msg, long when) {
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        if (msg.isInUse()) {
            throw new IllegalStateException(msg + " This message is already in use.");
        }

        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 {
                // 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值