Handler源码阅读记录

本文详细解读了Android中Handler的工作原理,从构造函数入手,解析如何通过Looper管理消息队列MessageQueue,以及Handler如何发送和处理消息,揭示了单链表在消息管理中的高效应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Handler源码阅读记录

 

我们从Handler的构造函数开始,一步一步查看Handler的内部源码,看其是如何实现自身的各种功能的。

首先从构造函数开始:

可以看到Handler在构造函数里最重要的一步是要获取Looper对象,如果没有获取到Looper对象,后面所有的工作都会进行不下去;从后面的代码可以看到,Looper内的消息队列被赋值给了Handler的消息队列,意味着Handler发送消息的目的地与Looper所持有并管理的消息队列相同,所以如果Looper为空就直接抛出错误了。


从发送消息的方法可以看出就是做了将消息插入MessageQueue中的操作。MessageQueue虽然名字为队列,但其实际内部数据结构为一个单链表数据结构来维护消息列表。(单链表在插入与删除上相比队列效率更高)

在插入消息到队列的方法中还可以看到将当前Handler的实例对象赋值给了msg.target;

而我们知道MessageQueue是由Looper管理的,那么我们来看一下Looper具体是如何实现对MessageQueue的管理的。

创建Looper对象必须要调用Looper.prepare()方法,从源码中可以看到,Looper内部有一个sThreadLocal容器来存放我们的Looper,这么做的主要目的是能保证每个线程获取到的Looper都是唯一的,ThreadLocal能为每个变量在每个线程都创建一个副本,从而不同线程改变自身线程内变量的值时不会影响其他线程。

从Looper对象的构造方法中可以看到消息队列也被同时创建。

那么在myLooper()方法中,很明显就是返回ThreadLocal容器中保存的Looper对象就好了。

紧接着我们来看Looper是怎么完成对MessageQueue的管理的:

对MessageQueue的管理主要是在loop()方法中实现。

可以看到方法首先对Looper是否为空进行了判断,然后获取Looper持有的消息队列,然后再下面我们可以看到一个for的死循环,在死循环中当获取到消息后调用了msg.target.dispatchMessage()方法,而msg.target就是发送该消息的Handler对象。

然后我们回到Handler的 dispatchMessage()方法,可以看到该方法里调用了一个我们很熟悉的、经常重写的handleMessage()方法。至此其实我们整个Handler的流程已经走通了。

最后放一张Handler的流程示意图给大家辅助理解。

希望这篇文章对您有所帮助,感谢您的阅读!

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值