美文网首页
Android Framework学习之消息屏障

Android Framework学习之消息屏障

作者: 一只二凡子 | 来源:发表于2023-01-02 17:10 被阅读0次

听说过消息屏障吗?

消息队列:单链表

消息类型:

    normal, 

    barrier(屏障), block其他消息

    async,相比normal多设置了一个异步标志位

如何想消息队列里插入屏障

屏障没有target(handler),因为不需要分发

也带了时间戳,插入队列时是按时间来排序,它只会影响它后面的消息

消息队列可插入多个屏障的

屏障插入消息队列后,没有唤醒线程去唤醒消息队列

插入屏障后会返回一个token(序列号),这个序列号用于后面撤除这个屏障用的

这个postSyncBarrier是private方法,只能通过反射调用, 手动插入一个没有target的消息进入队列会报错“message must have a target”

删除屏障后会唤醒线程(注意:添加屏障时没有唤醒线程)

获取消息时有屏障如何处理

nativePollOnce返回(唤醒线程)的3中情况:1:出错了,2: 超时了,消息的触发时间到了,3:有可读事件了

屏障只会block后面的normal消息,不能block后面的异步消息

插入消息时队列里有屏障会怎么处理

问题

1. 消息队列是空的时候,插一个屏障,会触发IdleHandler吗?

插入屏障不会唤醒线程(删除会),也就不会触发Idlehandler

2. 如果删除了屏障,消息队列空了,会触发IdleHandler吗?

    不会,IdleHandler已经被调用过了,不会再重复触发。处理完一条消息后,如果队列里没有消息了,就会触发idleHandler,处理完idlehandler后,再看队列里是否有消息,如果还是没有的话,这时线程进入休眠,不会再调用idlehandler, 如果有别的线程唤醒了这个线程,会再去检查队列是否为空,为空的话,是不会再触发这个idlehandler的。

3. 如果消息队列只有一个屏障消息,插入一个普通消息会idleHandler吗?

有可能,IdleHandler的触发逻辑:消息队列是空或第一条消息的触发时间还没到才会执行IdleHandler,所以关键是这个屏障的触发时间到了没有

4. 如果消息队列只有一个屏障消息,插入一个异步消息会idleHandler吗?

    有可能,IdleHandler的触发逻辑:消息队列是空或第一条消息的触发时间还没到才会执行IdleHandler,所以关键是这个屏障的触发时间到了没有

framework里哪些地方用到了屏障

scheduleTraversals会先插入一个屏障,block后面新的普通消息

当下一次VSync信号来时,执行mTraversalRunnable(调用doTraversal),删除屏障,优先执行异步消息performTraversal

demo,代码见资料

添加屏障

删除屏障

发送异步消息

总结

消息屏障:往队列里插入一个屏障,block住后面新的普通消息,主要是为了给异步消息开一个绿色通道,让其优先执行,比如UI绘制

异步消息:UI绘制,输入事件分发等,这些消息都是比较紧急的,不能被普通消息耽误了

相关文章

网友评论

      本文标题:Android Framework学习之消息屏障

      本文链接:https://www.haomeiwen.com/subject/pxghqdtx.html