Handler机制 是一种进程内部、线程间的通信机制,主要用于异步消息的处理。它涉及多个关键组件,包括Handler、Looper、MessageQueue和Message,共同协作以实现消息的发送、接收和处理。
Handler:负责发送消息和处理消息。当发出一个消息后,首先进入一个消息队列,发送消息的函数即刻返回,而另一个部分在消息队列中逐一将消息取出,然后对消息进行处理。这种机制通常用来处理相对耗时比较长的操作。
Looper:负责循环读取MessageQueue中的消息,读到消息之后就把消息交给Handler去处理。
MessageQueue:存储消息对象的队列。
Message:消息对象,是Handler机制中传递的基本单位。
为什么需要消息机制
Android规定访问UI只能在主线程中进行,在子线程中访问UI就会抛异常。但是Android又不建议在主线程中做耗时操作,导致ANR。所以,我们需要在子线程中做完耗时操作,然后去到主线程更新UI的办法。
Handler的主要作用是将一个任务切换到指定的线程中去执行。
分发机制:
Handler通过sendMessage()发送Message到MessageQueue队列;
Looper通过loop(),不断提取出达到触发条件的Message,并将Message交给target来处理;
经过dispatchMessage()后,交回给Handler的handleMessage()或者runnable来进行相应地处理。
消息的发送、入队:
//消息发送
Handler
//入队
MessageQueue为链表结构,发送的消息按照时间加入到链表中
消息的出队、分发:
//取出消息
MessageQueue
Handler
同步屏障(syncBarrier)
优先处理异步消息,拦住同步消息队列;
在MessageQueue中postSyncBarrier方法,内部会创建一个没有target(Handler对象)的消息。MessageQueue.next()方法中判断如果target为空且不为同步消息时取出异步消息;
发送异步消息:Message.setAsynchronous设置为异步消息,同时Handler构造方法也可设置。
关于同步屏障的使用,可了解绘制方法ViewRootImpl的scheduleTraversals。
内存泄露
Activity内使用Handler时,内部类Handler引用Activity对象,当消息未处理完成并关闭页面时,造成Activity对象无法回收造成内存泄漏;
/
为避免handler造成的内存泄漏
1、使用静态的handler,对外部类不保持对象的引用
2、但Handler需要与Activity通信,所以需要增加一个对Activity的弱引用
*/
private static class MyHandler extends Handler {
private final WeakReference mActivityReference;
MyHandler(Activity activity) {
this.mActivityReference = new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity activity = (MainActivity) mActivityReference.get(); //获取弱引用队列中的activity
//若引用,判断null
if(activity != null){
其他考虑问题:
1.一个线程有且仅有一个Looper,通过线程的数据存储类ThreadLocal存储,Looper构造函数中会创建MessageQueue。当handler把消息加入到消息队列时,Message内部配置了一个target(即Handler对象),这就可以保证Looper分发消息时对应哪个Handler去处理消息;
2.关于Message:发送的消息通过new Message或者Message.obtain()获得,Message内部维持了一个链表结构的缓存池sPool,sPool的最大容量为50,当消息处理完后recycle放入sPool中,当调用obtain()方法时会从缓冲池中取出消息再次使用,因此使用时最好通过此方法获取消息,可减少内存使用;
3.Handler为什么不会阻塞主线程,因为loop方法无线循环,为什么不会卡死?
真在卡死主线程的操作是某个消息处理时间过长发生ANR,而非循环。没有消息时会阻塞在loop的nativePollOnce方法中,此时主线程会释放CPU资源进入休眠状态,采用linux的ePoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。
4.发送消息post(Runnable)和sendMessage区别
callback不为空,即post,会把消息交给msg.callback处理。callback为空,即sendMessage,会判断Handler当前的mCallback(构造器传入)是否为空,不为空交给mCallback处理,否则调用Handler重写的handleMessage处理。
5.子线程使用Handler需要手动创建Looper并loop,至于主线程为什么不需要手动创建可自行了解。
6.Android其他实现异步的方式
继承Thread类
HandlerThread
IntentService
AsyncTask
线程池
其他欢迎补充
今天的文章 Handler机制分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/82798.html