美文网首页
Handler的工作流程 简单明了 一看就会

Handler的工作流程 简单明了 一看就会

作者: 夜明智灵 | 来源:发表于2021-02-23 16:50 被阅读0次

    Handler的工作流程类比成【传送带】的运作流程

    截图.png

    总共两个步骤 ->发送消息 和 调度消息

    1.发送消息

    Handler的不管是sendxxx还是postxxx方法 最终都会调用
    enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis)
    enqueueMessage 方法中会掉用 MessageQueue 的
    enqueueMessage(Message msg, long when)
    对比时间按时间先后,把消息插入到消息队列,以上完成消息的发送
    MessageQueue 是个优先级队列 按照时间先后顺序排队

    2. 调度消息

    Looper 轮询器 取消息
    通过loop()方法开启 轮询 消息队列MessageQueue.next()方法 。
    在 next()方法中轮询消息队列中的消息Messagae。
    首先会调用一个系统的native方法,nativePollOnce()检测当消息队列是否为空。如果为空会进入等待,不为空会 则会判断轮询到的消息需要发送的时间是否到了当前时刻,如果达到了就取出消息,没有则进行下一轮循环。
    取出消息后 调用msg.target.dispatchMessage() 完成消息调度
    这里 msg.target就是Handler

    ---------------------以上就是整个流程-----------------------

    附加

    Q:一个线程有几个Looper?如何保证?为什么?
    A:1个 ,
    通过静态方法prepare()创建Looper

    private static void prepare(boolean quitAllowed) {
           if (sThreadLocal.get() != null) {
               throw new RuntimeException("Only one Looper may be created per thread");
           }
           sThreadLocal.set(new Looper(quitAllowed));
       } 
    

    sThreadLocal.get()获取是否已经存了Looper,已经存在了就会抛出异常Only one Looper may be created per thread,否则 就设置一个Looper到ThreadLocal.ThreadLocalMap 的中

     public void set(T value) {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null)
                map.set(this, value);
            else
                createMap(t, value);
        }
    

    set的时候首先获取当前线程 ,然后获取线程的threadLocals变量,一个线程只有一个ThreadLocalMap ,所以值对应一个Looper
    这个ThreadLocalMap 是 ThreadLocal静态内部类

    相关文章

      网友评论

          本文标题:Handler的工作流程 简单明了 一看就会

          本文链接:https://www.haomeiwen.com/subject/xzorfltx.html