Handle和他的朋友们

官方描述

Handle通过线程的MessageQueue发送和处理Message和Runnable对象,每一个Handle实例和一个单例的Thread及它的MessageQueue相关联。
创建一个Handle的时候,他就绑定到线程及对应的MessageQueue,此后,Handle将会处理Message,把Message发送到MessageQueue,并且处理
从MessageQueue里出来的Message。Handle主要有两个作用:定时处理Message;把不同线程Action排队。通过不同的方法,可以马上执行也可以
延后执行。当app创建的时候(一个进程),主线程创建一个MessageQueue专门处理顶级对象(Activity、broadcast等)及其他Window相关对象。
开发者可以在新建的线程通过Handle与主线程交流。

相关关键人物

  • Handler
    发送及调整Message时机,取得与当前线程一致的Looper并循环,把Message压入MessageQueue。最终处理Message
  • Message
    中间流通的消息,携带处理方及自身属性
  • Looper
    循环,当MessageQueue里的消息到时的时候,取出Message,并通过Message的target把处理逻辑回到Handle
  • MessageQueue
    Message的队列,排序里边的Message,适当的时候取出来。消息不会直接添加到MessageQueue中,而是通过与Looper关联的{@link Handler}对象

源码分析

  • 创建handler时,初始化了handler内的looper、MessageQueue、callback
    public Handler(@Nullable Callback callback, boolean async) {
       .....
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
  • 创造消息
    这里刚开始sPool 为空,后边就开始复用了
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }
  • 发送消息最终调用方法
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
  • 准备开始去MessageQueue里排队,排队前把自身(handler)给了Message的target,这也为Handler内存泄露埋下了伏笔
    private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
            long uptimeMillis) {
        msg.target = this;
        msg.workSourceUid = ThreadLocalWorkSource.getUid();

        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }
  • looper.loop()发动,

 // sThreadLocal.get() will return null unless you've called prepare().
    @UnsupportedAppUsage
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

  /**
     * Return the Looper object associated with the current thread.  Returns
     * null if the calling thread is not associated with a Looper.
     */
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

    public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            try {
            // msg.target=handler
                msg.target.dispatchMessage(msg);
            } catch (Exception exception) {
              
            } finally {
              
            }
        

            msg.recycleUnchecked();
        }
    }
  • 再次回到Handler里
    /**
     * Handle system messages here.
     */
    public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
        // 一般情况为空,除非创建Message的时候设置或者用Handle的post
            handleCallback(msg);
        } else {
            if (mCallback != null) {
            // 一般情况下我们用handler的无参构造函数,所以这里大多情况也为空
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            // 这里便是我们创建handler之后,重新的那个
            handleMessage(msg);
        }
    }

消息处理流程

  • 首先创建Handle,并实现handleMessage,默认创建的Handle的变量callback是空
  • handle发送消息,最终调用sendMessageAtTime
  • 当前handle对象赋给当前Message的target变量
  • 排队。。。
  • Looper.loop,looper里有个MessageQueue,取出下一个最近的Message,调用Message的target的dispatchMessage方法,
  • 如果handle是调用的post,则post时的入参runnable赋给Message的callback(Runnable),否则Message的callback就是null
  • 最终回调给Handle的是
    • 如果Message的callback不为空,则有post时候的runnable的run方法接收
    • 如果Handle的callback不为空,则有创建Handle时候的callback的handleMessage接收
    • 以上都为空,则调用自己实现的handleMessage接收

结构图

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值