Handler源码分析
流程:sendMessage 开始 handleMessage 结束
sendMessage->enqueueMessage()->MessageQueue.enqueueMessage()
MessageQueue.enqueueMessage:是一个优先级队列 按照时间的先后顺序 单链表 到这里,这个消息就已经入了消息队列了
之后通过Looper ->loop()(死循环)->MessageQueue.next()(如果消息循环已经退出并被释放,则返回此处。)->dispatchMessage->handleMessage
(如果next()里面队列为空?next方法进来就会调用nativePollOnce,所以如果这个消息为空就会通知下层,native机制让这个消息处为等待以一个block(锁)状态 sendMessage可能是在子线程 Handle处理消息主线程)
一个线程可以有几个Handler?
n个
一个线程有几个Lopper?如何保证只有一个?
一个Lopper
Lopper函数里面使用prepare进行初始化,在prepare函数里面会用ThreadLocal new一个Lopper
ThreadLocal 是一个数组是一个keyValue的键值队 数组怎么存的呢? key是i也就是ThreadLocal value就是i+1也就是Lopper
Handler内存泄露的原因?为什么其他的内部类没有说过这个问题?
1.内部类持有外部类的引用导致内存泄漏
因为Hanlder里面可以获取当前Activity的this, 而获取了之后在Activity走了onDestory后但是在Handler里面引用了this,导致不会释放,导致了内存泄漏
一个MessageQueue持有Message而持有了一个Handler而一个Handler持有了外部类的一个this,如果Message没处理完不会被销毁,(耗时)
解决方案:静态内部类+弱引用。
将handler定义为静态内部类,再使用外部类的弱引用,这样,垃圾回收时会直接回收掉弱引用对象,不会再造成内存泄漏
如果想要在子线程new Handler要做什么准备?
所有的线程必须prepare() loop()所以子线程里面要new一个Handler必须要进行一个Looper的prepare和loop
MessageQueue如何保持各线程添加消息的线程安全?
因为无论多少子线程都是发送消息给主线程,而主线程只有一个Lopper,所以子线程发送的所有消息都是发送到MessageQueue
既然可以存在多个Handler往MessageQueue发送消息,那么内部如何保证线程安全呢?
因为线程里面有锁 synchronized 保证了线程安全(第一个线程没访问完,第二个线程就不能用所以delay延迟消息基本准确不能保证完全准确)
synchronized 可以修饰方法,静态方法,代码块
使用Message如何创建
用obtain 内存复用(一个线程池,每一个Message指向下一个Message链表方式.用完了之后做一个擦除操作进行复用)
如果用new Message会存在内存抖动,用完释放逐步增长