通过skia op指令了解LAYER_TYPE_HARDWARE

439 阅读1分钟

通识

作为Android开发,相信大家了解过ViewLayerType,知道在View播放动画的过程中,每一帧都需要重绘。而使用layertype去做优化,可以不用让每一帧都进行重绘。这其中就不得不提到LAYER_TYPE_HARDWARE

编码使用

先看下编码时如何使用:

view.setLayerType(View.LAYER_TYPE_HARDWARE, null)
ObjectAnimator.ofFloat(view, "translationY", 100f).apply {
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            view.setLayerType(View.LAYER_TYPE_NONE, null)
        }
    })
}

当一个ViewlayerType被设置为LAYER_TYPE_HARDWARE时,如果它的成员函数buildLayer()被调用,与它关联的RenderNode就会被设置成一个layer,此时该View将会作为一个FBO(Frame Buffer Object)进行渲染。

SKP直观分析

通过上面的描述可能不够直观,让我们从skiaop指令的角度出发,看看设置了LAYER_TYPE_HARDWAREview与没有设置的view刷新单帧时的差异。下面的内容涉及到抓取SKP(如何dump SKP,SKP抓取_android debugger.skia.org-CSDN博客,需要把收集root下),这里直接展示我验证的情况。

  1. 未设置LYAER_TYPE_HARDWARE 如图所示,我写了一个简易的页面,页面中有一个layout,其中包含9个ImageView,通过查看抓取到的一帧,可以发现op指令列表中存在9次DrawImageRect,op指令153条。 image.png

  2. 设置LYAER_TYPE_HARDWARE 而如果设置了LAYER_TYPE_HARDWARE,通过其单帧的SKP分析,则会发现所有op指令中直会有一次DrawImageRect,同时op指令也只有122条。 image.png

总结

为View设置LAYER_TYPE_HARDWARE,可以将布局内未发生变化的view缓存成一个图,在每帧绘制中,针对未发生变化的部分,只绘制一次,提高性能。