边写边整理:
一、一个线程有几个Handler?
二、一个线程有几个Looper?如何保证?
三、Handler内存泄漏的原因?为什么其他的内部类没有说过这个问题?
四、为何主线程可以new Handler?如果想要在子线程中new Handler要做些什么准备?
五、子线程中维护的Looper,消息队列无消息的时候的处理方案是什么?有什么用?
六、既然可以存在多个Handler往MessageQueue中添加数据(发消息时各个Handler可能处于不同线程),那它内部是如何确保线程安全的?
七、我们使用Message时应该如何创建它?
八、Looper死循环为什么不会导致应用卡死?
handler的执行流程
handler->sendMessage->MessageQueue.enqueueMessage(消息入队)
MessageQueue的数据存储结构,是(时间排序的)优先级队列的。 MessageQueue就是一个根据时间的先后顺序进行排序的优先级队列,这个队列的实施方案是链表,但是他的查找、插入等都符合队列的特征。
当一个新消息入队的时候,会for循环进行时间顺序判断,然后插入插入到指定位置。
入队时间顺序判断:新加入的时间,与之前的时间比对
当执行MessageQueue里的next方法时,里面只会不断将当前时间与队列第一个的时间进行对比,当当前时间大于队列第一个的时间时,把第一个msg返回。
Looper.loop不断调用MessageQueue.next->handler->handlerMessage
由于MessageQueue.next中的死循环,当msg存在的时候,就return,所以并没有真的死循环。
一、一个线程有几个Handler?
一个线程有多个handler
二、一个线程有几个Looper?如何保证?
一个线程有一个Looper =>原因:ThreadLocal
ThreadLocal是如何保证这点的?
ThreadLocal(线程隔离工具类)是一个 Map<key,Value>-><ThreadId,Value>
Map结构里面的Entry是一个顺序表,每个Entry都是一个键值对
Looper在prepare的时候,会调用ThreadLocal.set()方法,方法中传入Looper,而ThreadLocal的set方法中,会将ThreadLocal本身作为key,Looper作为value。所以ThreadLocal与Looper一一对应。 而ThreadLocal是一个final对象,所以key不会变,而为了防止value改变,Looper中的prepare中会判断ThreadLocal是否为空,当不为空的时候,会返回RuntiomeException,所以一个线程只能创建一个Looper。