Choreographer 翩翩起舞

/*** Callback type: Input callback. Runs first.* @hide*/public static final int CALLBACK_INPUT = 0;/*** Callback type: Animation callback. Runs before traversals.* @hide*/public static final int CALLBACK_ANIMATION = 1;/*** Callback type: Traversal callback. Handles layout and draw. Runs last* after all other asynchronous messages have been handled.* @hide*/public static final int CALLBACK_TRAVERSAL = 2;private static final int CALLBACK_LAST = CALLBACK_TRAVERSAL;

Choreographer, 黄油计划引入的协调器,实现了帧(就是Frame,因为有了垂直同步,所以可能Frame_callback是定期的)同步的功能, 负责同意协调所有的task的运行。

Choreographer 所支持的三种Task, 运行顺序: input > animation > traversal.

Choreographer 的getInstance() 返回的是 ThreadLocal的实例, 每个线程都有自己的Choreographer, 并且Choreographer使用的handler所依附也是该线程:

可以看到 Looper.myLooper()

// Thread local storage for the choreographer.private static final ThreadLocal<Choreographer> sThreadInstance =new ThreadLocal<Choreographer>() {@Overrideprotected Choreographer initialValue() {Looper looper = Looper.myLooper();if (looper == null) {throw new IllegalStateException("The current thread must have a looper!");}return new Choreographer(looper);}};<p>private Choreographer(Looper looper) {        mLooper = looper;        mHandler = new FrameHandler(looper);</p><p>…………………</p><p>}</p>FrameHandler 实现了自己的handleMessage:private final class FrameHandler extends Handler {public FrameHandler(Looper looper) {super(looper);}@Overridepublic 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;}}}注意上面的三类msg,处理的逻辑是不一样的:

doScheduleVsync() 和 doScheduleCallback()都没有真正的干活,

void doScheduleCallback(int callbackType) {synchronized (mLock) {if (!mFrameScheduled) {final long now = SystemClock.uptimeMillis();if (mCallbackQueues[callbackType].hasDueCallbacksLocked(now)) {scheduleFrameLocked(now);}}}}

比如doScheduleCallback: 先检查有没有Frame的CallBack已经被schedue了<如果有的话,在不久这些被post进来的task就可以被执行了,不需要再schedule一次>,如果没有,再看看当前的callBackQueue的第一个callback是否已经到期要执行.

如果到期要执行,那么就schedule一个 Frame的Callback:

private void scheduleFrameLocked(long now) {if (!mFrameScheduled) {mFrameScheduled = true;如果使用了V同步:if (USE_VSYNC) {if (DEBUG) {Log.d(TAG, "Scheduling next frame on vsync.");}// If running on the Looper thread, then schedule the vsync immediately,// otherwise post a message to schedule the vsync from the UI thread// as soon as possible.如果当前线程就是该Choreographer所属的线程if (isRunningOnLooperThreadLocked()) {直接schedule一个V同步.  scheduleVsyncLocked();做的事情:<mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;<pre name="code" class="html">mDisplayEventReceiver.scheduleVsync(); >} else { Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC); msg.setAsynchronous(true); mHandler.sendMessageAtFrontOfQueue(msg); } } else {否则就自己计算出下一个Frame的时间,然后send一个MSG_DO_FRAME的message:final long nextFrameTime = Math.max( mLastFrameTimeNanos / NANOS_PER_MS + sFrameDelay, now); if (DEBUG) { Log.d(TAG, "Scheduling next frame in " + (nextFrameTime – now) + " ms."); } Message msg = mHandler.obtainMessage(MSG_DO_FRAME);msg是异步的,不依赖严格的先后顺序. msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, nextFrameTime); } } }上面的FrameDisplayEventReceiver是一个实现了Runnable继承DisplayEventReceiver的类,其scheduleVsync(): /*** Schedules a single vertical sync pulse to be delivered when the next* display frame begins.*/public void scheduleVsync() {if (mReceiverPtr == 0) {Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "+ "receiver has already been disposed.");} else {nativeScheduleVsync(mReceiverPtr);}}onVsync()是收到了Vsync pulse之后的响应:/**     * Called when a vertical sync pulse is received.     * The recipient should render a frame and then call {@link #scheduleVsync}     * to schedule the next vertical sync pulse.     *     * @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}     * timebase.     * @param builtInDisplayId The surface flinger built-in display id such as     * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.     * @param frame The frame number.  Increases by one for each vertical sync interval.     */    public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {    }注意注释: * Schedules a single vertical sync pulse to be delivered when the next * display frame begins.

而Vsync里传递来的timestampNanos,就是本次pulse的时间戳。

而FrameDisplayEventReceiver的onVsync()函数做的事情是将作为runnable的自己send到所处的线程中去,注意是sendMessageAtTime,这里的时间是

变幻原是永恒,我们唯有用永恒的诺言制约世事的变幻。

Choreographer 翩翩起舞

相关文章:

你感兴趣的文章:

标签云: