Android Barrier

来源:互联网 发布:vm虚拟机ubuntu性能 编辑:程序博客网 时间:2024/06/05 15:13

为了让View能够有快速的布局和绘制,android中定义了一个Barrier的概念,当View在绘制和布局时会向Looper中添加了Barrier(监控器),这样后续的消息队列中的同步的消息将不会被执行,以免会影响到UI绘制,但是只有异步消息才能被执行。 所谓的异步消息也只是体现在这,添加了Barrier后,消息还可以继续被执行,不会被推迟运行。 如何使用异步消息,只有在创建Handler(构造方法的参数上标识是否异步消息)的时候或者在发送Message(Mesasge#setAsynchronous(true))时进行设置。而异步消息应用层是无法设置,因为相关设置的方法均是Hide的。


两种方式可以发送异步消息

1.在创建Handler时,在构造方法上传递参数true就可以,如下:

public Handler(Callback callback, boolean async) {        ...        mAsynchronous = async;    }
在Handler上设置异步的话,那么使用此Handler发送的消息都将被设置Mesasge#setAsynchronous(true)

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {        msg.target = this;        if (mAsynchronous) {            msg.setAsynchronous(true);        }        return queue.enqueueMessage(msg, uptimeMillis);    }
Message#setAsynchronous去设置,但是也是Hide的。 
/**     * Sets whether the message is asynchronous.     *     * Asynchronous messages represent interrupts or events that do not require global ordering     * with represent to synchronous messages.  Asynchronous messages are not subject to     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.     *     * @param async True if the message is asynchronous.     *     * @see #isAsynchronous()     * @see MessageQueue#enqueueSyncBarrier(long)     * @see MessageQueue#removeSyncBarrier(int)     *     * @hide     */    public void setAsynchronous(boolean async) {        if (async) {            flags |= FLAG_ASYNCHRONOUS;        } else {            flags &= ~FLAG_ASYNCHRONOUS;        }    }

当ViewRootImpl开始measure和layout ViewTree时,会向主线程的Handler添加Barrier

void scheduleTraversals() {        if (!mTraversalScheduled) {            mTraversalScheduled = true;            mTraversalBarrier = mHandler.getLooper().postSyncBarrier();            mChoreographer.postCallback(                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);            scheduleConsumeBatchedInput();        }    }
void unscheduleTraversals() {        if (mTraversalScheduled) {            mTraversalScheduled = false;            mHandler.getLooper().removeSyncBarrier(mTraversalBarrier);            mChoreographer.removeCallbacks(                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);        }


scheduleTraversals()方法都会在requestLayout时会被调用,所有导致布局变化的对会触发。例如:ViewGroup#addView,removeView或者View 从VISIBLE-->GONE,或者GONE-->VISIBLE等。




0 0
原创粉丝点击