Handler机制详解

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

Handler机制主要涉及到五个类

  • Handler (用于处理消息)
  • Message (消息对象)
  • MessageQueue (按一定顺序储存消息对象)
  • looper (内部是死循环, 不断从MessageQueue 中取消息)
  • HandlerThead

首先咱们来看一张Handler消息机制图

些许懵逼?

那咱们从源码开始入手,先从Handler.java开始

得出结论:

  • handler利用MessageQueue对象,调用其enquequeMessage方法将消息塞给MessageQueue

  • msg.target为handler自身对象

    那么enquequeMessage具体是怎么个塞法呢?

    得出结论:

    • enquequeMessage将传入的消息根据延时时间进行排序,0毫秒在前,非0毫秒在后

    咱们接着看Lopper.java

    得出结论

    • loop方法内部实际是一个死循环
    • 通过queque.next()从消息队列中取消息,如果没有消息就阻塞住,有消息就往下执行
    • 如果有消息, 通过dispatchMessage进行消息分发, 注意 这个dispatchMessage方法是Handler对象的

    进入到Message.java中

    得出结论:

    • 到最后调用了handleMessage交由用户去处理
    • 之所以系统创建多个Handler处理成百上千的消息而不会乱套,主要靠的就是target变量,相当于给每个消息绑定了一个Handler, 指定该Handler进行处理
    • 从sendMessage到handleMessage大致就是这么一个流程

    那么到此为止, 问题来了:

    • 前面说到, loop方法内部是一个死循环, 那这个循环是如果实在UI线程,岂不是会造成线程阻塞?

    android肯定不会允许这种情况发生的, 为了解决这个问题, HandlerThread上场了,单独开启了一个子线程用于handler

    HandlerThread继承自Thread进入到HandlerThread.java中我们先找到关键方法run

    得出结论:

    • perpare()主要用于初始化创建looper对象, 并将该对象存放到线程变量中,供线程对象使用
    • 初始化完成后调用loop方法开始死循环
    • 如果自己使用looper需要开启一个线程, 否则会阻塞UI线程, 并且调用perpare和loop方法
    • 平常我们在使用的handler的时候不需要开启线程, 是因为系统已经替我们开启了ActivityThread线程

    Handler消息分发流程

    附加

    ActivityThread中也有一个loop方法

    实际上, Android应用的启动运行靠的也是handler, 不断地处理系统消息, 这样四大组件才能正常运转起来

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享