Android贯穿两层的消息机制(Looper)

Android同一进程中线程的消息传递使用的主要方法就是MessageQueue+Message+Handle+Looper,该方法贯穿Native层和Java层,Java层的实现对于Android工程师来说较为容易理解,Native层由于设计到epoll等linux相关内容较难理解,下面将从MessageQueue的角度理解Native层的消息机制。

各个类的角色:
java层:
* MessageQueue:和Native层的MessageQueue一一映射,很多操作是native方法,通过Message内的next指针构成链表,也就是说所谓的Queue,而MessageQueue保存着链表头,其中Message对象按时间排序
* Message:jave层消息
* Handler:java层消息的消息处理者
* Looper:真正的轮询器,无论是java层消息还是native消息都是从这儿轮询的
native层:
* MessageQueue:内部有一个用来存储native消息的MessageEnvelope的容器,同样是按照native消息时间排序
* Message:native层消息
* Handler:java层Message的处理者(不包括callback)
* Looper:并不是真正的轮询器,只是native消息处理的方法类,不会轮询,轮询操作在Java层的Looper完成,这里的native looper只负责对native MessageQueue中的native消息的处理
* Request:回调消息,java层使用的是Runnable接口再转换成Message处理
* Respose:Request处理后的对象

一个带Looper的线程的启动流程:
1. java层Looper启动轮询器
2. 轮询器轮询MessageQueue.next函数
3. next函数首先调用native层MessageQueue的pollOnce函数,pollOnce函数用来从native MessageQueue的MessageEnvelope容器取消息
4. pollOnce函数会先处理没有函数回调的Respose(这儿不太懂,没有回调的Response的有啥用)
5. pollOnce通过epoll写入一个管道描述符,用来监控这个管道,也会把所有的Request存储的描述符一同监控,若这些描述符没有事件发生epoll_wait函数就会阻塞在这儿,如果有线程往这个管道描述符或Request中的描述符中写入东西,epoll_wait就会停止阻塞继续执行。

此外native的Looper有一个addFd函数,用来向epoll中加入Request,也就是加入描述符的epoll监控
6. epoll_wait完成后会返回哪些描述符发生了变化,循环这些变化把对应的Reques转换成Respose,再把MessageEnvelope容器中已经到时间执行的Message取出来调用它相关的Handler的回调方法,这里MessageEnvelope和之前epoll传入的管道描述符对应,所以无论是管道中写入数据,还是Request的描述符写入数据都将取出Message,最后把Request转换成的Respose中的回调执行
7. pollOnce执行完毕,native消息的一次轮询完成
8. 继续执行next方法将会从java层的MessageQueue取Message作为返回值,返回给java层轮训器
9. java层Looper得到Mesasge执行java层消息,这样一次循环完成了一次native消息的处理和一次java层消息的处理,

值得注意的是一次循环native可能处理个多个消息,而java层只处理了一个消息,并且native消息先执行,若native没有消息就会阻塞线程,若有消息则执行,接下来才执行java层消息

总结:真正的轮询器在java层,两边有一一对应的MessageQueue但是功能不同,其他的类之间没有任何直接联系,native Looper依靠java层next函数执行多个native消息,java Looper只用next取出java 层消息对象Message,Message的执行在Looper中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值