文章目录
Handler 作用
Handler是用来处理异步消息, 实现进程线程间通信。
Handler异步消息处理流程
1 Handler发送Message
2 mesage添加到MessageQueen
3 Looper循环取出消息。
4 通知Handler处理。
Handler相关核心类
Handler
Handler用来发送消息和处理消息通知。
Handler在构造方法中实例了Looper对象,Looper的构造中创建了MesageQueen队列。
最终Handler调用sendMessageAtTime方法此时将当前Handler传入了Message.target方法,调用Queen的enqueenMessage方法,将消息添加到消息队列中。
MessageQueen
MessageQueen是一种单链表的数据结构,用来存储Message,存储时会根据Message中When字段根据时间进行排序。
Looper.loop()方法循环取出Message。
Looper
在Looper初始化的时候。创建了MessageQueen和获取当前线程。创建的Looper会保存在ThreadLocal中。
在调用Looper.Loop()方法时调用queen.next()方法获取message,通过Handler的dispatchMessage方法发送消息
Message
消息实体类,when字段根据时间进行排序,target字段保存当前消息发送给哪个handler。
线程中handler和looper的对应关系?
一个线程可以有多个Handler但是只能有一个Looper。
主线程没有创建Looper为什么可以直接使用Handler?
首先我们需要了解ActivityThread这个类,ActivityThread就是我们常说的UI主线程,他的main方法就是我们App程序的启动入口,在main方法中,已经给我们创建了Looper。并且开启了Looper.loop()循环。
ActivityThread
Looper为什么不会阻塞,没有消息是是怎么处理的?
Looper.loop()什么不会阻塞主线程?
在ActivitThread中可以看到,Activity的生命周期是依赖主线程的Looper.loop,如果某个消息处理时间过长就会造成卡顿。
或者anr异常。
而且主线程Looper从消息队列读取消息,当读完所有消息时,主线程阻塞。子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。因此loop的循环并不会对CPU性能有过多的消耗。
SendMessage和PostMessage的区别?
sendMessage 和postMessage最终都是调用了sendMessageAtTime的方法。本质上是没有区别的。
postMessage是将runnable当做Message中的callback属性封装成了一个空的消息,消息直接在run方法中进行处理。
主线程怎么通知子线程?
HandlerThread
HandlerThread是继承自Thread,本质上是一个线程类。
Handler有自己的内部Looper,可以实现Looper循环
通过获取HandlerThread的Looper作为参数传入Hander可一直接在HandleMessage中执行异步任务。
创建HandlerThread对象必须先调用start对象,创建Looper。