Handler原理简说

       有关Handler原理的文章已经烂大街了,有很多文章写的特别棒。这篇文章其实是我想自己简短总结一下自己的理解,和我个人当初在学习时,比较疑惑的地方。

Handler是干什么的?
       个人理解:它是一个用来发送消息,并且自己处理这个消息的一个通信工具。(自己发自己处理?对!)关键是它可以在不同线程发送或处理消息
 
使用场景:
       主要用于线程间的通信。
 
原理:
       handler发出一个消息,放入到一个容器,外部启动一个死循环,不停的判断容器中是否有消息,有就拿出来,还给handler处理。

 
怎么就实现在线程间通信了?
       只说关键流程:
1、在线程A中要预先创建一个Looper, 同时在Looper中会创建一个MessageQueue对象。

2、在线程A中创建Handler对象并重写了handleMessage方法,等待消息到来处理消息。也就是处理消息的线程是线程A。在Handler构造方法中,会去拿到上面这个Looper对象,和Looper中的MessageQueue对象

3、在线程B发送消息,Handler会把消息放入到MessageQueue中,但在这之前,把自己赋值给了这个Message的target变量。 也就是说,在消息中会有一个target变量就是当初发送自己的handler对象

4、调用Looper中的loop()方法。方法开启了一个死循环,判断当前Looper中的MessageQueue中是否有消息Message,如果有就调用该消息的target变量(handler对象)的dispatchMessage()方法。

5、处理消息,在Handler中的dispatchMessage()方法中分发消息,判断具体把消息交给handler的那个回调方法处理。

最后结果就是,线程B中发出的消息,在线程A中得到处理。。。注意第4步流程,可以直接在第1步之后做,总之是要开启这个死循环。

       其他文章还介绍了ThreadLocal, 这里也说下,ThreadLocal可以创建一个只属于线程自己的变量,这个变量与其他线程是隔离的,不会被共享。线程A中创建的Looper对象就是放到了的ThreadLocal中。Handler构造中也是通过ThreadLocal去拿到的Looper对象。

就不贴代码了吧。其他文章都有,这里就是自己做个小总结。

当初疑惑的地方
为什么这么设计?
        我不知道还有其他的办法,来实现类似的功能。在看一些文章和听一些人讲解后,应该只有这种方式可以满足此类场景的的需求。就是在一个线程中及时处理其他线程发过来的消息。必须要有一个循环来不停的检查是否有消息传递。还有就是考虑到要想一个Android程序保持运行状态,就必须有代码一直在执行,不能写个阻塞在程序里吧,还要不停的刷新UI。这个死循环的设计正好可以满足。(从ActivityThread中的main()来思考)

Looper.loop()死循环,不阻塞线程吗?不消耗cpu资源吗?
        首先上面也提到了Looper.loop()在ActivityThread中调用是等于是保持了程序的运行状态,每一次循环等于一次完整的刷新逻辑。只要loop()中每次循环过程是流畅的,展现给我们看到的就是流畅的操作。只有你在loop()中的某次循环中写了一个死循环,导致loop()循环卡主了,我们才会看到应用卡了。
有消息正常处理,正常消耗cpu资源,当没有消息时候,线程会释放CPU资源进入休眠状态。具体涉及到Linux epoll的阻塞 唤醒机制。到这里,我就停止了。

同一个线程中创建多个Handler,消息不会乱吗?
        target! 每个消息都有保存了自己的Handler对象,分发消息时候当然知道是哪个handler去处理(步骤3)。那handler放在MessageQueue中可以吗?这样就不用每个消息都存个handler了。不可以!同一个线程中,多个Handler拿到的MessageQueue是同一个。一个线程可以创建多个Handler,但只能有一个Looper,一个Looper中只能有一个MessageQueue(查看Looper.prepare()源码)。也就是说,同一个线程中Handler共享同一个Looper和MessageQueue。

处理消息有优先级吗?
        可以说有,也可以说没有,看你怎么理解优先级这个概念了。Message中是没有设置优先级这种字段的。但有一个setAsynchronous(boolean async)方法,可以把消息标识成异步消息。Message消息本质上没有优先级,但它有3种类型,1、同步消息(平常我们发的都是),2、异步消息,3、屏障消息(没有target)。发送了一个屏障消息之后,会先处理异步消息,阻塞住同步消息,直到屏障消息移除。这么来看也可说通过同步屏障来控制处理消息的优先级了。

文章所描述的观点问性问题,是出于自己的认知,不保证正确。欢迎指正文章错误。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值