Choreographer原理
Choreographer启动流程
在Activity启动过程,执行完onResume后,会调用Activity.makeVisible(),然后再调用到addView(), 层层调用会进入如下方法:
public ViewRootImpl(Context context, Display display) {
...
//获取Choreographer实例
mChoreographer = Choreographer.getInstance();
...
}getInstance()
//frameworks/base/core/java/android/view/Choreographer.java
public static Choreographer getInstance() {
return sThreadInstance.get();
}
// Thread local storage for the choreographer.
private static final ThreadLocal<Choreographer> sThreadInstance =
new ThreadLocal<Choreographer>() {
@Override
protected Choreographer initialValue() {
//获取当前线程Looper
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
创建FrameHandler
postCallback
postCallbackDelayedInternal
创建FrameDisplayEventReceiver
DisplayEventReceiver
nativeInit
创建NativeDisplayEventReceiver
NativeDisplayEventReceiver继承于LooperCallback对象,此处mReceiverWeakGlobal记录的是Java层 DisplayEventReceiver对象的全局引用。
initialize
DisplayEventDispatcher继承LooperCallback
监听mReceiver的所获取的文件句柄,一旦有数据到来,则回调this(此处NativeDisplayEventReceiver)中所复写LooperCallback对象的 handleEvent。
Vysnc回调流程
handleEvent
processPendingEvents
遍历所有的事件,当有多个VSync事件到来,则只关注最近一次的事件。
dispatchVsync
此处调用到Java层的DisplayEventReceiver对象的dispatchVsync()方法,接下来进入Java层。
Choreographer对象实例化的过程,创建的对象是DisplayEventReceiver子类 FrameDisplayEventReceiver对象,接下来进入该对象。
onVsync
可见onVsync()过程是通过FrameHandler向主线程Looper发送了一个自带callback的消息,此处callback为FrameDisplayEventReceiver。 当主线程Looper执行到该消息时,则调用FrameDisplayEventReceiver.run()方法.
run()
doFrame()
此处frameTimeNanos是底层VSYNC信号到达的时间戳。
每调用一次scheduleFrameLocked(),则mFrameScheduled=true,能执行一次doFrame()操作,执行完doFrame()并设置mFrameScheduled=false;
最终有4个回调类别,如下所示:
INPUT:输入事件
ANIMATION:动画
TRAVERSAL:窗口刷新,执行measure/layout/draw操作
COMMIT:遍历完成的提交操作,用来修正动画启动时间
doCallbacks
该方法主要功能:
从队列头mHead查找CallbackRecord对象,当队列头部的callbacks对象为空或者执行时间还没到达,则直接返回;
开始执行相应回调的run()方法;
回收callbacks,加入对象池mCallbackPool,就是说callback一旦执行完成,则会被回收。
CallbackRecord
这里的回调方法run()有两种执行情况:
当token的数据类型为FRAME_CALLBACK_TOKEN,则执行该对象的doFrame()方法;
当token为其他类型,则执行该对象的run()方法。
那么需要的场景便是由WMS调用scheduleAnimationLocked()方法来设置mFrameScheduled=true来触发动画, 接下来说说动画控制的过程。
动画显示过程
参考
最后更新于