Handler源码分析-学习笔记

102 阅读42分钟

以上图大家都很熟悉了,流程不多介绍了

几个重要的点是:

简而言之就是:handler发送消息,消息入队列,入队的时候按时间排序,looper循环取出消息队列的第一个消息,并调用消息持有的handler把消息分发出去,handler处理消息(handleMessage方法)。

怎么体现它从子线程切换到主线程的呢?

内存不分主线程和子线程,内存在主线程和子线程都可以用,所以才有了一块内存(message)移动到另一个地方(消息传递)。

如果不断往队列里面发消息,而不处理,那么消息队列可能会爆满,进而卡顿,内存可能会消耗完。

MessageQueue:由 单链接实现的优先级队列,先进先出

MessageQueue的排序算法是什么?插入排序

looper关键信息点:

ThreadLocal:线程隔离工具类,

如何保证一个线程里面只有一个looper?

首先一个线程有唯一的threadLocal,threadLocal有一个threadLocalMap,这个threadLocalMap<唯一的ThreadLocal,value>长这样,然后value是looper。 

在prepare的时候sthreadLocal会先get一下,在去set,如果get的时候不为空,直接抛异常。

以上是最外层的,

补充一个细节,就是MessageQueue跟随looper创建,并且messagequeue是final类型的,一旦创建就无法被修改,也保证了MessageQueue的唯一,MessageQueue是队列,不属于哪一个线程,MessageQueue属于哪个线程的这个说法是错误的,

线程-->ThreadLocalMap<唯一的ThreadLocal,looper> --->Looper---->MessageQueue.

handler泄漏原因?

 handler 持有外部activity类引用,而Message持有Handlder,假设当一个延时十分钟的消息放在消息队列里面一直等待执行,当外部activity销毁的时候,jvm通过可达性分析到,activity被handler引用,handler被Message持有,而Message在等待,那么activity就无法被回收,就产生内存泄漏了。这里根本原因是activity的生命周期和Message的生命周期不一致,

MessageQueue核心原理:

子线程中维护的looper,消息队列无消息的时候的处理方案是什么?有什么用?

子线程中当消息队列没有消息的时候要调用quit方法,为什么呢,子线程中没有消息的时候队列是在等待(睡眠),调用quit方法的时候会唤醒线程并在MessageQueue里面返回一个null,随后退出loop。

问题:既然可以存在多个handler往MessageQueue中添加数据(发消息的时候各个hanadler可能处于不同线程),那它内部是如何保证线程安全的?

使用synchronized,内置锁,也称同步锁,在插入和取消息的时候都有加锁,以保证安全。