2.32 Choreographer原理
1 minute read
2.32.1 启动流程(注册监听)
- 创建
ViewRootImpl
public ViewRootImpl(Context context, Display display) {
...
// Choreographer.getInstance();创建Choreographer并放到当前线程的ThreadLocal, 即应用主线中
mChoreographer = Choreographer.getInstance();
...
}
- 构造
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];
...
}
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;
}
}
}
FrameDisplayEventReceiver
private final class FrameDisplayEventReceiver extends DisplayEventReceiver
implements Runnable {
public void run() {
doFrame(mTimestampNanos, mFrame);
}
}
DisplayEventReceiver
, 注册vsync
public DisplayEventReceiver(Looper looper, int vsyncSource) {
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
vsyncSource);
}
android_view_DisplayEventReceiver#nativeInit()
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj) {
...
status_t status = receiver->initialize();
...
}
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事件回调
android_view_DisplayEventReceiver#handleEvent
int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) {
...
//分发Vsync
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
...
}
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);
...
}
DisplayEventReceiver#dispatchVsync
private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
// 抽象想法, 子类实现
onVsync(timestampNanos, builtInDisplayId, frame);
}
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);
}
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);
...
}
参考