Android卡顿真的是因为”掉帧“,不看绝对血亏

}

}

并不是每个垂直同步信号都会被上层订阅并处理,只有当Choreographer订阅了下一个垂直同步信号,SurfaceFlinger才会把信号通过onVsync()回调给上层。

图中第一个垂直信号到来之前,上层调用了postCallback()Choreographer抛绘制任务,同时订阅了下一个信号并把mFrameScheduled置为 true,表示需要绘制下一帧。当第一个信号产生时,onVsync()被回调,同时将doFrame()抛到主线程执行,执行完毕后将mFrameScheduled置为 false,因没有后续订阅动作,所以上层不会收到后续的onVsync()回调,也不会绘制任何新东西。

执行绘制任务


ViewRootImplChoreographer抛绘制任务后,任务并没有立马执行,而是被暂存在绘制任务链中,并注册接收下一个垂直同步信号。只有当下一个信号通过onVsync()回调后,它才会被执行:

public final class Choreographer {

// 垂直同步信号接收器

private final class FrameDisplayEventReceiver extends DisplayEventReceiver implements Runnable {

private boolean mHavePendingVsync;

private long mTimestampNanos;

private int mFrame;

@Override

public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {

// 发送异步消息到主线程,执行当前的Runnable,即doFrame()

Message msg = Message.obtain(mHandler, this);

msg.setAsynchronous(true);

mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);

}

@Override

public void run() {

mHavePendingVsync = false;

// 绘制一帧的内容

doFrame(mTimestampNanos, mFrame);

}

}

}

每当垂直同步信号回调时,都会向主线程推送一个待执行的绘制帧任务doFrame()

public final class Choreographer {

void doFrame(long frameTimeNanos, int frame) {

final long startNanos;

synchronized (mLock) {

// 如果没有订阅这一帧的垂直同步信号,则直接退出不绘制

if (!mFrameScheduled) {

return; // no work to do

}

try {

// 处理这一帧的输入事件

doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);

// 处理这一帧的动画

doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);

// 处理这一帧的 View 树遍历

doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);

// 所有绘制任务结束后执行 COMMIT 任务

doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);

} finally {

}

}

}

绘制每一帧时,会按照“输入事件”、“动画”、“View 树遍历”、“COMMIT”这样的顺序处理任务。

处理函数doCallback()定义如下:

public final class Choreographer {

// 暂存绘制任务的链式数组

private final CallbackQueue[] mCallbackQueues;<

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值