当前位置: 首页>前端>正文

屏障消息为什么不直接插入消息队列的头部 android消息屏障

同步屏障:

发送异步消息的关键就是要消息开启一个同步屏障。屏障的意思即为阻碍,顾名思义,同步屏障就是阻碍同步消息,只让异步消息通过

屏障消息为什么不直接插入消息队列的头部 android消息屏障,屏障消息为什么不直接插入消息队列的头部 android消息屏障_屏障消息为什么不直接插入消息队列的头部,第1张

如上图所示,在消息队列中有同步消息和异步消息(黄色部分)以及一道墙----同步屏障(红色部分)。有了同步屏障的存在,msg_2 和 msg_M 这两个异步消息可以被优先处理,而后面的 msg_3 等同步消息则不会被处理。那么这些同步消息什么时候可以被处理呢?那就需要先移除这个同步屏障

举个栗子:

开演唱会的时候,观众们需要在体育馆门口排队依次检票入场(这些排队的观众相当于消息队列中的普通同步消息),但这个时候演唱会的嘉宾来了(相当于异步消息,优先级高于观众),如果他们出示证件(不出示证件,就相当于普通观众入场,也还是需要排队),保安立马拦住进场的观众(保安拦住普通观众就相当于开启了同步屏障,阻止同步消息通过),让嘉宾先进去(只处理异步消息,而阻挡同步消息)。等工作人员全部进去了,如果保安不再阻拦观众(即移除同步屏障),这样观众又可以进场了(又可以处理同步消息)。只要保安不解除拦截,那么后面的观众就永远不可能进场(不移除同步屏障,同步消息就不会得到处理)。

同步屏障使用场景

似乎在日常的应用开发中,很少会用到同步屏障。那么,同步屏障在系统源码中有哪些使用场景呢?Android 系统中的 UI 更新相关的消息即为异步消息,需要优先处理。

比如,在 View 更新时,draw、requestLayout、invalidate 等很多地方都调用了ViewRootImpl#scheduleTraversals(),这里就开启了同步屏障,并发送异步消息,由于 UI 更新相关的消息是优先级最高的,这样系统就会优先处理这些异步消息。最后,当要移除同步屏障的时候需要调用ViewRootImpl#unscheduleTraversals()

总结

同步屏障的设置可以方便地处理那些优先级较高的异步消息。当我们调用Handler.getLooper().getQueue().postSyncBarrier() 并设置消息的setAsynchronous(true)时,target 即为 null ,也就开启了同步屏障。当在消息轮询器 Looper 在loop()中循环处理消息时,如若开启了同步屏障,会优先处理其中的异步消息,而阻碍同步消息。

Q&A:

ViewRootImpl中的同步屏障逻辑有并发问题,如果是异步更新UI,会导致屏障无法移除,最终引发ANR。


https://www.xamrdz.com/web/2pa1924711.html

相关文章: