Handler 消息发送机制实现原理解析

Handler 消息发送机制实现原理解析

对于Handler消息发送机制,相信大家都不陌生,但是怎么发送可能就不是太清楚了,为了加深印象特此总结,个人总结一句话:

向哪个线程发送消息就在哪个线程中创建Handler。

我们大多数情况都是在子线程向主线程发送消息,一般都没什么问题。但是怎么从主线程向子线程发送消息呢?
咱们先创建一个子线程

var thread = Thread(object :Runnable{
            override fun run() {
//                Looper.prepare()
                mHandlerTwo = object : Handler() {
                    override fun handleMessage(msg: Message) {
                        super.handleMessage(msg)
                        if (msg.what==201){
                            ToastUtils.showShort(msg.obj.toString())
                        }
                    }
                }
//                Looper.loop()
            }

        }).start()

然后在主线程中添加点击事件发送信息

var msg = Message.obtain()
                msg.what=201
                msg.obj = "收到主线程中的信息"
                mHandlerTwo.sendMessage(msg)

当我们点击后发现会没有反应或者抛异常
在这里插入图片描述
从给出来的信息我们可以看到,创建Handler的前提是必须先执行Looper.prepare(),但是我们为啥在主线程创建Handler时不需要Looper.prepare(),因为主线程中系统已经帮我们实现了这个方法。大家都知道App也有入口,是Main函数,但是我们的Main函数在哪儿呢?我们看ActivityThread这个类,搜索Main如图:
在这里插入图片描述
这里的Looper.prepareMainLooper() 就相当于Looper.prepare(),所以我们在主线程中不需要在添加Looper.prepare()方法Handler也可以正常收发消息。
个人总结 Handler通信之前三步骤:
一、调用Looper.prepare()
二、创建Handler对象
三、调用Looper.loop()

Handl 消息发送机制

主要涉及到四个类
1、Looper:消息遍历者
2、Message:消息
3、MessageQueue:队列消息
4、Hanlder:消息的发起者、接受者

我们从Handler通信之前三步骤入手进行总结:
一、Looper.prepare()
Ctrl + 鼠标左键 查看源码
在这里插入图片描述
可以看到一个线程中只能存在一个Looper对象,如果有多个的话就会抛异常,继续点击进去查看Looper构造函数都干了啥
在这里插入图片描述
此方法里面创建了一个消息队列,并将当前线程赋值给mThread,结合上面的Looper.prepare()方法可以看出 消息队列(MessageQueue)也只能存在一个。

总结
Looper.prepare()的作用
1、创建Looper对象
2、创建MessageQueue对象
3、获取当前线程

二、Handler()
同样我们Ctrl + 鼠标左键查看Handler的构造函数都干了啥
在这里插入图片描述
我们可以看到在构造方法中 Handler 获取到了 Looper对象 和MessageQueue,在源码中看到没有创建Looper对象会抛出异常,所以子线程中必须通过Looper.prepare()方法来获取Looper对象,否则Handler是没办法发送和接收消息的。
总结
Handler()
1、得到Handler对象
2、获取Looper和Message对象

三、Looper.loop()
常规操作,Ctrl + 鼠标左键,查看该方法干了啥
在这里插入图片描述
同样的它也是获取Looper对象 和MessageQueue,最后我们看这个for循环,这是一个无限循环,我们通过Message msg = queue.next()可以看出,可以看出for循环的作用是从消息队列里获取消息的,在创建Handler时都会重写一个handleMessage方法来接收消息,现在我们只要找到这个方法今天的总结就结束了。不买官司了就在我们的For循环中

msg.target.dispatchMessage(msg);

到此Handler分发机制总结完毕,感谢您的阅读。动动你的手点个赞呗!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值