美文网首页
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