Choreographer(编舞者)用来控制同步处理输入(Input)、动画(Animation)、绘制(Draw)三个UI操作。
在View的绘制流程的WindowManagerGlobal.java类中,addView()
方法的root = new ViewRootImpl(view.getContext(), display)
进行初始化操作,其中的构造方法中mChoreographer = Choreographer.getInstance();
,
public static Choreographer getInstance() {
return sThreadInstance.get();
}
其中进入sThreadInstance
private static final ThreadLocal<Choreographer> sThreadInstance =
new ThreadLocal<Choreographer>() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException("The current thread must have a looper!");
}
Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
if (looper == Looper.getMainLooper()) {
mMainInstance = choreographer;
}
return choreographer;
}
};
其中Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP)
为初始化Choreographer。
在构造方法中,mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper, vsyncSource) : null
代码进行了FrameDisplayEventReceiver
初始化,其中开启了onVsync
回调,进行vsync信号的接收。根据屏幕的刷新速率,进行接收vsync信号,然后通过handler进行更新。
通过流程图过程,进入到Choreographer的postCallbackDelayedInternal
方法中,将其通过类型mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token)
添加到CallbackRecord
的单向链表中,其中通过obtainCallbackLocked
方法对
private CallbackRecord obtainCallbackLocked(long dueTime, Object action, Object token) {
CallbackRecord callback = mCallbackPool;
if (callback == null) {
callback = new CallbackRecord();
} else {
mCallbackPool = callback.next;
callback.next = null;
}
callback.dueTime = dueTime;
callback.action = action;
callback.token = token;
return callback;
}
对dueTime,action,token进行赋值。
其中从ViewRootImpl
的scheduleTraversals
方法中,mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null)
看到类型为Choreographer.CALLBACK_TRAVERSAL
,action为mTraversalRunnable
,token为null
。
其中继续通过scheduleFrameLocked()
进入handler的doScheduleVsync()-》scheduleVsyncLocked()-》mDisplayEventReceiver.scheduleVsync()
进行开启Vsync信号的分发,然后调用到nativeScheduleVsync()
底层native方法中。
进行vsync信号分发后,在Choreographer
中的FrameDisplayEventReceiver
的onVsync()
方法中进行接收,通过mHandler(what没传默认为0)
进入doFrame()
方法中,其中
mFrameInfo.markInputHandlingStart();
doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
mFrameInfo.markAnimationsStart();
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
mFrameInfo.markPerformTraversalsStart();
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
调用doCallbacks()
方法,其中
callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(
now / TimeUtils.NANOS_PER_MS);
if (callbacks == null) {
return;
}
通过callbackType从mCallbackQueues中进行取值,在前面说过的mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null)
则得到添加进入的类型为Choreographer.CALLBACK_TRAVERSAL,则可拿到callbacks的值不为null,通过
for (CallbackRecord c = callbacks; c != null; c = c.next) {
if (DEBUG_FRAMES) {
Log.d(TAG, "RunCallback: type=" + callbackType
+ ", action=" + c.action + ", token=" + c.token
+ ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime));
}
c.run(frameTimeNanos);
}
进入到CallbackRecord
的
public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);
} else {
((Runnable)action).run();
}
}
run()方法中,之前传入的token为null,则执行((Runnable)action).run()
代码,其中action为ViewRootImpl的mTraversalRunnable
,执行它的run()方法,
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
通过doTraversal()->performTraversals()
,执行View的绘制步骤performMeasure
、performLayout
和performDraw
方法进行绘制。