先把结论放在前面:掉帧的判定标准是"这一帧的工作没有在下一个 VSync 之前完成",而不是"某一帧耗时超过了 16 毫秒"。这两者看似等价,实际差别很关键:一个 60 Hz 设备上,某帧耗时 20 毫秒,如果它恰好在 VSync 之前完成,就不算掉帧;如果耗时 18 毫秒但在 VSync 之后才完成,就会掉帧。 理解这个时序关系,是卡顿分析的第一步。
面试里这题属于"性能与渲染的基础题",也是最容易暴露基础是否扎实的题。答得浅的是"16 毫秒算一帧,超过就是掉帧";答得深的是能讲清 VSync 信号如何驱动渲染、Choreographer的回调顺序与同步屏障、doFrame里 measure/layout/draw 与渲染提交的关系,以及"主线程慢"与"主线程被抢占"两类卡顿在 trace 上的区别。
VSync 驱动的渲染循环
Android 的渲染是由 VSync 信号触发的自持循环,核心逻辑在Choreographer。
/** Choreographer 的帧回调顺序:这是理解掉帧的关键 */ final class Choreographer { // 回调阶段,按顺序执行 static final int CALLBACK_INPUT = 0; // 输入事件处理 static final int CALLBACK_ANIMATION = 1; // 动画计算 static final in