Handler源码分析————实现Handler机制核心架构

此篇笔记用来记录一下在网易公开课上学习的Handler源码分析

在此之前本人对Handler的处理消息的机制架构也有一定的理解,但是还是没有网易大佬啃的透彻,特此学习,十分感激

Handler:

Android SDK中用来处理异步消息的核心类,(像我们我的okhttp,retrofit,asyncTask等都是可以采用异步处理更新ui)

子线程可以通过Handler来更新ui

 

lopper轮循器

实际上looper和messageQueue的关系是是上图,而第一个图是为了我们能够更好的看明白handler和messageQueue和looper的关系

关键问题:1为什么handler能够切换线程更新UI:这个问题比较深入,但是很简单,

在Android的 入口类AcytivityThread中main方法中系统自动给我们创建了looper 如下

 

而我们main方法则在主线程中,so~ 我们的looper是自动在在主线程中的啦,然后再进行looper.loop方法取出发送到handerMessage中,而Handlermessage也是在主线程中的所以我们能够在主线程中取到消息更新ui啦

 

2:整个消息队列为什么只有一个messageQueue

源码中每个队列只有一个looper,他又只创建了一个MessageQueue    so~MessageQueus只有一个啦

 

1. Handler 的回调方法是在 Looper.loop()所调用的线程进行的;

2. Handler 的创建需要先调用 Looper.prepare() ,然后再手动调用 loop()方法开启循环;

3. App 启动时会在ActivityThread.main()方法中创建主线程的 Looper ,并开启循环,所以主线程使用 Handler 不用调用第2点的逻辑;

4. 延时消息并不会阻塞消息队列;

5. 异步消息不会马上执行,插入队列的方式跟同步消息一样,唯一的区别是当有消息屏障时,异步消息可以继续执行,同步消息则不行;

6. Callback.handleMessage() 的优先级比 Handler.handleMessage()要高*

7. Handler.post(Runnable)传递的 Runnale 对象并不会在新的线程执行;

8. Message 的创建推荐使用 Message.obtain() 来获取,内部采用缓存消息池实现;

9. 不要在 handleMessage()中对消息进行异步处理;

10. 可以通过removeCallbacksAndMessages(null)或者静态类加弱引用的方式防止内存泄漏;

11. Looper.loop()不会造成应用卡死,里面使用了 Linux 的 epoll 机制。

说下 handler 机制,Looper 通过 MessageQueue 取消息,消息队列是先进先出模式,那我延迟发两个消息,第一个消息延迟2个小时,第二个消息延迟1个小时,那么第二个消息需要等3个小时才能取到吗?

回顾问题,我们来解答:

  • MessageQueue 的实现不是队列,不要被名称迷惑,他是一个链表

  • 每次发送消息都会按照 delay 从小到大进行重排

  • 所有的 delay 消息都是并行的,不是串行的

  • 第一个延迟2个小时,第二个延迟1小时,会优先执行第二个,再过1小时执行第一个           

  • MessageQueue 存消息的时候是使用当前时间进行排序的,有兴趣的同学可以自己查看看源码~


版权声明:本文为weixin_40350174原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。