落叶知秋|程序员必懂的Android 技术之 VSYNC、 Choreographer 起源( 四 )


Choreographer 的主要功能是 , 当收到 VSYNC 信号时 , 去调用通过 postCallback 设置的回调方法 。 目前一共定义了四种类型的回调 , 它们分别是:

  1. CALLBACK_INPUT:优先级最高 , 和输入事件处理有关;
  2. CALLBACK_ANIMATION:优先级其次 , 和 Animation 的处理有关;
  3. CALLBACK_TRAVERSAL:优先级最低 , 和 UI 等空间绘制有关;
  4. CALLBACK_COMMIT:最后执行 , 和提交任务有关(在 API Level 23 添加) 。

优先级的高低和处理顺序有关 。
当收到 VSYNC 信号时 , Choreographer 将首先处理 INPUT 类型的回调 , 然后 ANIMATION 类型 , 最后才是 TRAVERSAL 类型 。
另外 , Android 在 4.1 还对 Handler 机制进行了略微改造 , 使之支持 Asynchronous Message(异步消息) 和 Synchronization Barrier(同步屏障) 。
一般情况下同步消息和异步消息的处理方式并没有什么区别 ,
只有在设置了同步屏障时才会出现差异 。
同步屏障为 Handler 消息机制增加了一种简单的优先级关系 , 异步消息的优先级要高于同步消息 。
简单点说 , 设置了同步屏障之后 , Handler 只会处理异步消息 。
以 View 的绘制流程为例:
void scheduleTraversals() {if (!mTraversalScheduled) {mTraversalScheduled = true;// 同步屏障 , 阻塞所有的同步消息mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();// 将 UI 绘制任务发送到 Choreograhper// 注意mTraversaRunnable是一个Runnable对象mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);// ...}}scheduleTraversals 首先禁止了后续消息的处理能力 , 一旦设置了消息队列的 postSyncBarrier , 所有非 Asynchronous 的消息将被停止派发 。
UI 绘制任务设置了 CALLBACK 类型为 TRAVERSAL 类型的任务 , 即 mTraversalRunnable:
final class TraversalRunnable implements Runnable {@Overridepublic void run() {//开始执行绘制遍历doTraversal();}}Choreographer 的 postCallback 方法将会申请一次 VSYNC 中断信号 , 通过 DisplayEventReceiver 的 scheduleVsync 方法 。 当 VSYNC 信号到达时 , 便会回调 Choreographer 的 doFrame 方法 , 内部会触发已经添加的回调任务:
// 回调 INPUT 任务doCallbacks(Choreographer.CALLBACK_INPUT, mframeTimeNanos);// 回调 ANIMATIONdoCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);// 回调 View 绘制任务 TRAVERSALdoCallbacks(Choreographer,CALLBACK_TRAVERSAL, frameTimeNanos);// API Level 23 新增 , COMMIT doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);此时 UI 绘制任务 doTraversal 方法被回调 , 即在 Android 4.1 之后 ,UI 绘制任务被放置到了 VSYNC 中断处理中了 。 Choreographer 确实做到了统一协调管理 UI 的绘制工作 。
有关于参考Android核心知识点笔记github:


推荐阅读