Handler详解

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。

ThreadLocal(本地线程存储变量)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值