Android 8.0系统源码分析--Message发送、处理过程源码分析

本文深入分析Android 8.0系统中Message的发送和处理过程,从Handler.sendMessage的调用来探究Message如何进入MessageQueue,并讨论了直接重写Handler.dispatchMessage的潜在问题,建议遵循重写handleMessage的方法处理消息。
摘要由CSDN通过智能技术生成

     上节我们分析了应用进程中的Looper和MessageQueue创建过程,接下来我们来看看Message是如何发送到当前的MessageQueue上并且它是如何得到处理的。

     一、Message的发送过程

     发送一个Message对于应用来说,非常简单,就是调用handler.sendMessage方法,就可以将一个封装好的Message发送出去了,或者调用handler.post(Runnable r)也可以,两种调用往下的实现是完全一样的。我们就以sendMessage为入口来看一下Message发送的过程。该方法的实现在Handler.java类中,目录路径为frameworks\base\core\java\android\os\Handler.java,sendMessage方法的源码如下:

    public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);
    }
	
	
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
	
	
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }


     参数delayMillis表示当前的Message的延迟时间,上面的逻辑都很简单,最终是调用enqueueMessage来将一条消息入队的,enqueueMessage方法的源码如下:

    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

     该方法的第一句就是给当前的message的target赋值,表示该message最终由谁处理,一般我们都会构造自己的handler,所以最终该消息得到分发的时候,目标就是我们重写的handler了,接着调用queue局部变量的enqueueMessage方法来将该message入队,queue局部变量的类型为MessageQueue,它指向的就是执行当前逻辑的Looper对象的mQueue成员变量,也就是上一节我们分析Looper创建过程中创建好的。MessageQueue类的目录路径为frameworks\base\core\java\android\os\MessageQueue.java,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 false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }

     该方法中前面的逻辑的目的就是寻找到一个合适的位置,把当前的message对象挂载进去,上一节我们已经说了MessageQueue类的mMessages成员变量,它的类型为Message,而Message又是一个单向链表,可以不断的往它的成员变量next上指定下一个message,所以只要发送message,就会不断的往上面一个合适的节点挂载。挂载完成后根据局部变量needWake的值来判断是否要唤醒当前的Looper循环,如果我们发送的message需要延迟,而且时间没到
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红-旺永福

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值