Android中Handler源码解析(二)

上次我们谈到Handler和Looper关联,Looper又与主线程进行关联,所以Handler就与整个主线程中的消息队列进行了关联,接下来我们看一下消息是如何被处理的,代码如下:

    /**
     * Run the message queue in this thread. Be sure to call
     * {@link #quit()} to end the loop.
     */
    public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;//1:获取消息队列

     //代码省略
        for (;;) {//这是一个死循环,消息循环
            Message msg = queue.next(); // 2:消息逐个取出
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            // 代码省略
            msg.target.dispatchMessage(msg);//3:在Handler中处理消息
            //代码省略
            msg.recycleUnchecked();//4:回收消息
        }
    }

Looper总结:通过Looper.prepare()来获取Looper对象,消息队列封装在Looper对象中,并保存在sThreadLoal中,然后通过Looper中loop();死循环中,从消息队列中逐个去处理消息。
大家看到第3步中有一个msg.target.dispatchMessage(msg);msg是Message对象,而target则是Handler对象,源码如下:

public final class Message implements Parcelable {

    /*package*/ Bundle data;

    /*package*/ Handler target;

    /*package*/ Runnable callback;

消息总结:说白了,消息就是转了一个圈,Handler将消息post给消息队列,消息队列又分发给Handler,
接下来我们看一下Handler中处理消息的方法

    //消息处理,子类必须继承该方法
    public void handleMessage(Message msg) {
    }
    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

dispatchMessage只是一个分发方法,如果Runnable类型的callback为空,则执行handlerMessage来处理,如果为空,则将更新UI的代码放在这里,如果callback不为空,则执行handlerCallBack来处理,则会调用Runnable中的run方法,这就是Handler消息分发的两种类型,当post(Runnable callback) 则callback不为空,当我们使用Handler来sendMessage时候,通常不会设置callback,也就执行了handlerMessage

    public final boolean post(Runnable r){
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
    private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
    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) {
            //代码省略
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
   private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;//设置当前target为当前Handler对象
        //代码省略
        return queue.enqueueMessage(msg, uptimeMillis);//将当前对象插入到消息队列中
    }

从上述代码可以看出,在post(Runnable callback)时会将Runnable包装成Message对象,最终会将消息插入到消息队列,此外sendMessage也是类似实现

总结:不管是哪种分发,Handler都会将消息追加到MessageQueue中,再经过不断循环,Android程序就运行起来了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值