Android(安卓)Barrier
16lz
2021-01-25
为了让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等。
更多相关文章
- Android(安卓)应用进程启动过程
- Android(安卓)圆形ProgressBar风格设置
- Android获取屏幕分辨率及DisplayMetrics简介 和java获得屏幕宽度
- ActivityManagerService解读之进程管理computeOomAdjLocked方法
- 整理一下Android的面试题
- Android(安卓)Service和IntentService知识点详细总结
- Android控件 vs Flutter控件
- Android之Gradle的理解
- Android适应方案汇总(三)