异步消息处理机制-Handler

Handler面试详解

一、什么是handler

handler通过发送和处理MessageRunnable对象来关联对应线程的MessageQueue.

1. 可以让对应的MessageRunnable在未来的某个时间点进行相应处理2.让自己想要处理的耗时操作放在子线程,让更新ui的操作放在主线程

Ps.子线程不能开启handler,因为消息队列默认绑定UI线程

 

一、handle的使用方法

1.post(runnable)

 

2.sendMessage(message)

 

二、handler的机制原理

消息机制主要包含:MessageQueueHandlerLooper这三大部分,以及Message,下面我们一一介绍。

 

**Message**需要传递的消息,可以传递数据;

**MessageQueue**消息队列,但是它的内部实现并不是用的队列,实际上是通过一个单链表的数据结构来维护消息列表,因为单链表在插入和删除上比较有优势。主要功能向消息池投递消息(MessageQueue.enqueueMessage)和取走消息池的消息(MessageQueue.next)

**Handler**消息辅助类,主要功能向消息池发送各种消息事件(Handler.sendMessage)和处理相应消息事件(Handler.handleMessage)

**Looper**不断循环执行(Looper.loop),从MessageQueue中读取消息,按分发机制将消息分发给目标处理者。

 异步消息处理机制-Handler

源码分析:

Handler构造方法(有LooperMessgeQueue

 异步消息处理机制-Handler

 

 

初始化Looper:LooperprepareMainLooper()方法中的prepare()创建Looper设置ThreadLocal,保证了每个线程的Looper的维系

 异步消息处理机制-Handler

 异步消息处理机制-Handler

开启Looper:Looperloop()方法(从MessageQueue中死循环获取消息并处理消息,targetHandlerdispatchMessage来处理消息)

 异步消息处理机制-Handler

 

 

总结:在子线程执行完耗时操作,当Handler发送消息时,将会调用MessageQueue.enqueueMessage,向消息队列中添加消息。当通过Looper.loop开启循环后,会不断地从线程池中读取消息,即调用MessageQueue.next,然后调用目标Handler(即发送该消息的Handler)的dispatchMessage方法传递消息,然后返回到Handler所在线程,目标Handler收到消息,调用handleMessage方法,接收消息,处理消息。

 异步消息处理机制-Handler

 异步消息处理机制-Handler

 

三、handler引起的内存泄漏以及解决办法

原因:静态内部类持有外部类的匿名引用,导致外部activity无法释放

解决办法:handler内部持有外部activity的弱引用,并把handler改为静态内部类,mHandler.removeCallback()