Handler机制详解

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, 不断地处理系统消息, 这样四大组件才能正常运转起来

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

0%