1. 作用
当 vsync 信号来临时执行相应逻辑
2. 数据结构
1. 单个 callback
private static final class CallbackRecord {
public CallbackRecord next;
public long dueTime;
public Object action;
public Object token;
}
next : 链表形式,指向下一个同类型的 callback
dueTime : 最晚执行时间
action :可以是以下 3 种类型
- Runnable: 无参 task
public interface Runnable {
public abstract void run();
}
public void postCallback(int callbackType, Runnable action, Object token)
- FrameCallback: 参数为 long 的 task
public interface FrameCallback {
public void doFrame(long frameTimeNanos);
}
public void postFrameCallback(FrameCallback callback)
- VsyncCallback : 参数为 FrameData 的 task
public interface VsyncCallback {
void onVsync(@NonNull FrameData data);
}
void postVsyncCallback(@NonNull VsyncCallback callback)
token:
private static final Object FRAME_CALLBACK_TOKEN = new Object() {
public String toString() { return "FRAME_CALLBACK_TOKEN"; }
};
private static final Object VSYNC_CALLBACK_TOKEN = new Object() {
public String toString() {
return "VSYNC_CALLBACK_TOKEN";
}
};
token作用:CallbackRecord 执行 action 的时候,需要根据 token 不同,来强制转换成不同的类型
public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);
} else {
((Runnable)action).run();
}
}
void run(FrameData frameData) {
frameData.setInCallback(true);
if (token == VSYNC_CALLBACK_TOKEN) {
((VsyncCallback) action).onVsync(frameData);
} else {
run(frameData.getFrameTimeNanos());
}
frameData.setInCallback(false);
}
2. callback 队列
private final class CallbackQueue {
private CallbackRecord mHead;
public void addCallbackLocked(long dueTime, Object action, Object token);
boolean hasDueCallbacksLocked(long now);
CallbackRecord extractDueCallbacksLocked(long now)
public void removeCallbacksLocked(Object action, Object token);
}
专门管理 CallbackRecord 的数据结构:
mHead 指向第一个 CallbackRecord,进而可以对 callback 队列进行增删查改
3. callback 声明:
private final CallbackQueue[] mCallbackQueues;
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
for (int i = 0; i <= CALLBACK_LAST; i++) {
mCallbackQueues[i] = new CallbackQueue();
}
- 是个数组
- 每个索引处存放不同类型的 callback 队列(CallbackQueue)
callback 类型:
//事件类型
public static final int CALLBACK_INPUT = 0;
//动画类型处理动画的最终显示结果
public static final int CALLBACK_ANIMATION = 1;
//一个动画可能有多个动画复合而成,这个类型主要处理这类
public static final int CALLBACK_INSETS_ANIMATION = 2;
//界面的布局刷新
public static final int CALLBACK_TRAVERSAL = 3;
//app 暂时不管
public static final int CALLBACK_COMMIT = 4;
private static final int CALLBACK_LAST = CALLBACK_COMMIT;
4. app 使用接口
public void postFrameCallback(FrameCallback callback) {
postFrameCallbackDelayed(callback, 0);
}
public void postFrameCallbackDelayed(FrameCallback callback, long delayMillis) {
callback, FRAME_CALLBACK_TOKEN, delayMillis);
}
public void postVsyncCallback(@NonNull VsyncCallback callback) {
}
1.callback 的添加
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
//超过最晚时间马上执行
if (dueTime <= now) {
scheduleFrameLocked(now);
//扔到 handler 消息队列中,等待执行
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
2. callback 执行:按照如下顺序
doCallbacks(Choreographer.CALLBACK_INPUT, frameIntervalNanos);
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameIntervalNanos);
doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameIntervalNanos);
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameIntervalNanos);
doCallbacks(Choreographer.CALLBACK_COMMIT, frameIntervalNanos);