从 sendEmptyMessage 开始,一步步解剖Handler

 工作的时候发现自己对于很多东西用起来得心应手,原理机制也背诵的滚瓜烂熟,但是一问到源码脑子就....瓦特了!所以最近准备从头开始学习源码,学习大神们优秀的思想!


本文是对Handler机制的源码分析,目的是为了能够从源码角度一点点的理解Handler机制,里面会出现大量的源码,所以会比较枯燥,但是只要认真看完,相信你一定会对Handler机制的实现方法有更加清晰的认识


        Handler是用起来非常简单!
private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //处理接收到的消息
        }
    };
初始化之后,在子线程进行完耗时操作之后,使用
 
 handler.sendEmptyMessage(what)

 好了,现在就从sendEmptyMessage 方法开始,一步步的解析handler整个工作流程  — — 注意,Handler开始向消息队列发送消息了;


 点进去之后,我们会发现,sendEmptyMessage  、sendMessage 最终都是在调用 sendMessageAtTime 方法,将发送的消息放入messgeQueue;需要注意的一点是,sendMessageDelayed方法中,已经将 delayMillis 延迟时间转换成了  SystemClock.uptimeMillis() + delayMillis,指的是该消息被取出来执行的时间,这一点会在MessageQueue中显的比较重要
    //直接调用 sendEmptyMessageDelayed 方法
    public final boolean sendEmptyMessage(int what){
        //直接调用 sendEmptyMessageDelayed 方法
        return sendEmptyMessageDelayed(what, 0);
    }


// 被sendEmptyMessage方法调用,delayMillis 为0,同时将参数转换成message后调用 sendMessageDelayed 此处已经和 sendMessage方法调用同一个路径了
    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
      //将参数进行复制,转换成 Message 
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageDelayed(msg, delayMillis);
    }


    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
      //此处的 SystemClock.uptimeMillis() + delayMillis 用来计算消息的执行时间
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }


   //最终,发送消息的方法都会走到这里,将消息放入MessageQueue 
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
      //mQueue 是从哪里来的?此处先放下,待会回头来分析
        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);
    }


在sendMessageAtTime 方法中,消息放入了我们熟知的 handler机制中的MessageQueue;现在我们分析 sendMessageAtTime 方法,这个方法中主要执行了一个 MessageQueue 的非空判断,然后就直接执行了enqueueMessage方法,mQueue 是从哪里来的呢?为了逻辑的连贯性,此处先不分析,会放到下面进行分析,这里先接着enqueueMessage进行分析;
 
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
      //将此Hanlder赋值给Message,用来在分发消息时候接收消息的hanlder
        msg.target = this;
        if (mAsynchronous) {//是否是异步,此处为false,不会执行
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }


enqueueMessage方法也很简单,主要就是将此Hanlder赋值给Message,用来在分发消息时候接收消息的hanlder,然后将消息交给messageQueue来处理;
好了,到这里,我们开始进入messageQueue 了--
当然,并不是Handler源码已经分析完毕了,只是我按照代码的脚步一步一步的走下去,目的是为了让自己能清除的看到Handler机制走过的所有道路,以便于最终能够完整、清晰的理解Handler消息机制,最后还是会回到Handler中的;

现在,我们进入MessageQueue — — 注意:Handler发送的消息,要进入消息队列了;


 直接找到 Handler中 enqueueMessage方法里面执行的MessageQueue方法, enqueueMessage(Message msg, long when);

  boolean enqueueMessage(Message msg, long when) {
      
// msg.target ,这个参数是不是很熟悉,对的,就是在Handler进入MessageQueue之前的enqueueMessage方法中赋值的,是当前的Handler
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        if (msg.isInUse()) {//此处判断当前Message是否是被执行了,一个消息不能被执行使用两次
            throw new IllegalStateException(msg + " This message is already in use.");
        }
 synchronized (this) {
            if (mQuitting) {//mQuitting默认一直是false,只有执行quit 方法,并且该MessageQueue能被安全退出的时候回被赋值为true,主线程中是不能被退出的,所以一直都是false,因此不会被执行进来ÿ
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值