此篇笔记用来记录一下在网易公开课上学习的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 存消息的时候是使用当前时间进行排序的,有兴趣的同学可以自己查看看源码~