android同步障碍物消息和异步消息

同步障碍物消息和异步消息

1、sync barrier message(同步障碍物消息)特点:msg.target==null;

异步消息特点:msg.setAsynchronous(true);

下面是从MessageQueue中取消息(next方法)的代码片段:

if (msg!= null && msg.target == null) {

    do {

          prevMsg = msg;

          msg = msg.next;

    } while(msg != null && !msg.isAsynchronous());

}

含义:如果messageQueue的头部是barrier消息,最终遍历得到的msg只能是异步消息或者null,也就是如果barrier消息后面有异步消息,处理异步消息,如果后面没有异步消息(null),则阻塞,直到被唤醒。

2、barrier消息、异步消息使用场景:确保优先执行view的绘制流程

     在ViewRootImpl的scheduleTraversals方法中,先向消息队列中post一个barrier消息,接着再post一个异步消息,这个异步消息就是view绘制流程的触发器,也就是当looper循环到这个异步消息,进行处理时才会进行view的绘制流程,在执行这个异步消息后,会remove掉之前post的barrier消息。

3、添加的idlehandler执行时机:当从消息队列中获取消息时,消息队列中没有消息或者是barrier消息,这个时候就会执行idlehandler的动作,但是这个动作的执行时间不能过长,否则下次取消息的时间就会被推迟。

队列中同步消息处理流程

1、如果sendEmptyMessageDelayed发送了消息A,延时为500ms,消息先进入队列,在next方法中会计算是否到达延迟时间,如果没达到,会触发nativePollOnce方法,阻塞looper线程,等待下一个消息进入队列唤醒,或者是Delayed时间结束,自动唤醒; 

 2、在1的前提下,如果紧接着又sendEmptyMessage了消息B,B没有延时,B消息进入队列,但这时A的阻塞时间还没有到,于是把B插入到A的前面,然后调用nativeWake()方法唤醒looper线程;

3、唤醒之后,会重新读取队列,这时B在A前面,不需要等待,于是直接返回给Looper;

4、Looper处理完该消息后,会再次调用next()方法,如果发现now大于A.when则返回A消息,否则计算下一次该等待的时间。

在什么情况下新插入的消息会唤醒looper线程:

1、队列中没有消息;

2、新插入的消息没有延时;

3、新插入的消息的延时时间小于队列头部消息的延时时间;

4、队列头部是一个障碍物消息,并且新插入的消息是最早需要执行的异步消息。

如果有分析不正确的地方,请大神们指正。

你可能感兴趣的:(android同步障碍物消息和异步消息)