Handler源码解析1

Handler源码解析1

https://blog.csdn.net/qq_44076155/article/details/110676740

Handler源码解析2

https://blog.csdn.net/qq_44076155/article/details/110687066

 

 

Handler:发送和接收消息

Looper:用于轮询消息队列,一个线程只能有一个Looper

Message: 消息实体

MessageQueue: 消息队列用于存储消息和管理消息

 

 

 

handler机制就是一个传送带的运转机制。

1)MessageQueue就像履带。

2)Thread就像背后的动力,就是我们通信都是基于线程而来的。

3)传送带的滚动需要一个开关给电机通电,那么就相当于我们的loop函数,而这个loop里面的for循环就会带着不断

的滚动,去轮询messageQueue

4)Message就是 我们的货物了

 

 

App启动时,调用ActivityThread.main   

创建主线程的looper并且开始loop处理事务

 

looper的创建

通过prepare方法,static final 修饰的唯一threadLocal变量保证了一个线程只能有一个looper

 

 

流程分析

 

子线程handler-》sendMessage   -> messasgeQueue.enqueueMessage   //消息队列队列的插入节点

looper.loop()->  messasgeQueue.next()-》handler.dispatchMessage()->handler.handleMessage()

 

1.handler的各种发送消息的方式都会进入下面方法,并且为msg设置target

2.然后调用MessageQueue的enqueueMessage

看源码发现消息队列是一个由单链表实现的优先级队列

以msg的when来进行排序,并且使用了插入排序算法

3.有了消息和消息队列,还需要有一个开关Looper.loop

源码中loop方法主体是一个死循环,唯一的退出方式是,当msg==null

中途通过queue.next不断的从MessageQueue中取出消息

4.那什么时候msg会等于null?再来看看MessageQueue.next方法

同样是一个死循环,而且有两种情况会进行阻塞    1.没有到msg的执行时间    2.消息队列为空

消息队列为空时,在next时已经阻塞起来了,所以不会返回null

下面有一行,if命中则会返回为null

继续查找源码,发现只有在MessageQueue.quit里面才会把mQuitting置为true

也就是说只有调用quit方法后才能结束loop

而且在主线程中不允许调用这个方法,因为loop结束了,整个app进程也就结束了

5.最后又回到loop里面,获取到msg后,调用dispatchMessage分发消息,由上面我们知道msg.target就是发送消息的那个handler

dispatch里面调用了handleMessage,到次完成整个流程

 

哪一个handler发送的msg,就会分发到哪一个handler上,由此,可以在线程1中用mhandler sendMessage

然后在线程2中写 handleMessage 实现线程间的通信

 

一个线程对应一个looper      一个lopper对应一个MessageQueue,1线程 1loopper 1messageQueue

而MessageQueue的next  enqueueMessage 都是使用的对象锁

因此 1个线程只有一个可以操作MessageQueue 的地方

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值