2.32 Choreographer原理

1 minute read

2.32.1 启动流程(注册监听)

  1. 创建ViewRootImpl
public ViewRootImpl(Context context, Display display) {
    ...
    // Choreographer.getInstance();创建Choreographer并放到当前线程的ThreadLocal, 即应用主线中
    mChoreographer = Choreographer.getInstance();
    ...
}
  1. 构造Choreographer
  private Choreographer(Looper looper, int vsyncSource) {
        ...

        mHandler = new FrameHandler(looper);
        mDisplayEventReceiver = USE_VSYNC
                ? new FrameDisplayEventReceiver(looper, vsyncSource)
                : null;
        ...
        mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
        ...
    }
  1. FrameHandler
  private final class FrameHandler extends Handler {
      ...
      public void handleMessage(Message msg) {
          switch (msg.what) {
              case MSG_DO_FRAME:
                  doFrame(System.nanoTime(), 0);
                  break;
              case MSG_DO_SCHEDULE_VSYNC:
                  doScheduleVsync();
                  break;
              case MSG_DO_SCHEDULE_CALLBACK:
                  doScheduleCallback(msg.arg1);
                  break;
          }
      }
  }
  1. FrameDisplayEventReceiver
  private final class FrameDisplayEventReceiver extends DisplayEventReceiver
            implements Runnable {

     public void run() {
         doFrame(mTimestampNanos, mFrame);
     }
  }
  1. DisplayEventReceiver, 注册vsync
   public DisplayEventReceiver(Looper looper, int vsyncSource) {
        mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
                vsyncSource);

   }
  1. android_view_DisplayEventReceiver#nativeInit()
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj) {
    ...
    status_t status = receiver->initialize();
    ...
}

  1. android_view_DisplayEventReceiver#initialize()
status_t NativeDisplayEventReceiver::initialize() {
    // 监听mReceiver的文件句柄, 当有数据则回调NativeDisplayEventReceiver#handleEvent())
    ...
    int rc = mMessageQueue->getLooper()->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
            this, NULL);
    ...
}

2.32.2 Vsync事件回调

  1. android_view_DisplayEventReceiver#handleEvent
int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) {
  ...
  //分发Vsync
  dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
  ...
}
  1. android_view_DisplayEventReceiver#dispatchVsync
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    ...
    // 调用java层的#dispatchVsync()方法
    env->CallVoidMethod(receiverObj.get(),
            gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count);
    ...
}
  1. DisplayEventReceiver#dispatchVsync
  private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
    // 抽象想法, 子类实现
    onVsync(timestampNanos, builtInDisplayId, frame);
  }

  1. FrameDisplayEventReceiver#onVsync
  public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
    ...
    // 向主线程发送消息, 即执行run
    Message msg = Message.obtain(mHandler, this);
    mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
    ...
  }

  public void run() {
    doFrame(mTimestampNanos, mFrame);
  }
  1. Choreographer#doFrame()

  void doFrame(long frameTimeNanos, int frame) {
    ...
    doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
    doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
    ...
  }

  void doCallbacks(int callbackType, long frameTimeNanos) {
    ...
    callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(
                    now / TimeUtils.NANOS_PER_MS);
    ...
    // 执行callbacks
    callbacks.run(frameTimeNanos);
    ...
  }

参考