异步消息处理机制-Handler
Handler面试详解
一、什么是handler
handler通过发送和处理Message和Runnable对象来关联对应线程的MessageQueue.
1. 可以让对应的Message和Runnable在未来的某个时间点进行相应处理2.让自己想要处理的耗时操作放在子线程,让更新ui的操作放在主线程
Ps.子线程不能开启handler,因为消息队列默认绑定UI线程
一、handle的使用方法
1.post(runnable)
2.sendMessage(message)
二、handler的机制原理
消息机制主要包含:MessageQueue,Handler和Looper这三大部分,以及Message,下面我们一一介绍。
**Message:**需要传递的消息,可以传递数据;
**MessageQueue:**消息队列,但是它的内部实现并不是用的队列,实际上是通过一个单链表的数据结构来维护消息列表,因为单链表在插入和删除上比较有优势。主要功能向消息池投递消息(MessageQueue.enqueueMessage)和取走消息池的消息(MessageQueue.next);
**Handler:**消息辅助类,主要功能向消息池发送各种消息事件(Handler.sendMessage)和处理相应消息事件(Handler.handleMessage);
**Looper:**不断循环执行(Looper.loop),从MessageQueue中读取消息,按分发机制将消息分发给目标处理者。
源码分析:
Handler构造方法(有Looper和MessgeQueue)
初始化Looper:Looper中prepareMainLooper()方法中的prepare()创建Looper设置ThreadLocal,保证了每个线程的Looper的维系
开启Looper:Looper的loop()方法(从MessageQueue中死循环获取消息并处理消息,target为Handler,dispatchMessage来处理消息)
总结:在子线程执行完耗时操作,当Handler发送消息时,将会调用MessageQueue.enqueueMessage,向消息队列中添加消息。当通过Looper.loop开启循环后,会不断地从线程池中读取消息,即调用MessageQueue.next,然后调用目标Handler(即发送该消息的Handler)的dispatchMessage方法传递消息,然后返回到Handler所在线程,目标Handler收到消息,调用handleMessage方法,接收消息,处理消息。
三、handler引起的内存泄漏以及解决办法
原因:静态内部类持有外部类的匿名引用,导致外部activity无法释放
解决办法:handler内部持有外部activity的弱引用,并把handler改为静态内部类,mHandler.removeCallback()