Android渲染优化之视过度绘制、减少嵌套

学习自:

https://mp.****.net/postedit


如果刷新频率是60hz,每16ms就会打一次信号,请求一个绘制。所以一个绘制不要超过16ms。

如果1秒绘制了60帧,那么它的fps就是60。


比较显著的一个问题就是过度绘制

Android渲染优化之视过度绘制、减少嵌套

开发者选项中可以开启查看


原色:没有过度绘制
蓝色:1 次过度绘制
绿色:2 次过度绘制
粉色:3 次过度绘制
红色:4 次及以上过度绘制


模拟器自带的设置界面过度绘制是非常严重的(但是这个界面几乎不会更新,所以无伤大雅)

Android渲染优化之视过度绘制、减少嵌套


我们写的一个demo无过度绘制

Android渲染优化之视过度绘制、减少嵌套


又写了个demo

Android渲染优化之视过度绘制、减少嵌套

发现一个ViewGroup包含一个View的情况,无法避免View的那个地方绘制两次。

目前有3个思路:

1.可能他有api可以解决,我目前不知道这个api,还在百度和问朋友之中

2.自定义控件,但是这样修改起来非常的不灵活。可是目前只能通过这个方法来凑合了。

3.自定义ViewGroup,拿到所有控件占的有颜色区域,在绘制背景的时候进行拦截,仅绘制余下的区域。这个方法实现难度挺大的,但是如果实现了,效果会非常的好。


对于自定义控件进行的优化

Android渲染优化之视过度绘制、减少嵌套

代码

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawRect(0, 0, 100, 100, paint);
    canvas.drawRect(20, 0, 120, 100, paint);
    canvas.drawRect(40, 0, 140, 100, paint);
}

我画了3个边长为100的正方形,左起始左边偏移20。

可以看到明显的过度绘制。

所以需要用clipRect去裁剪画布以进行一个优化。


现在我把需要画的区域裁剪下来

Android渲染优化之视过度绘制、减少嵌套

成功解决过度绘制

代码

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();//保存未裁剪前的画布
    canvas.clipRect(0, 0, 20, 100);
    canvas.drawRect(0, 0, 100, 100, paint);

    canvas.restore();//回滚未裁剪前的画布
    canvas.save();
    canvas.clipRect(20, 0, 40, 100);
    canvas.drawRect(20, 0, 120, 100, paint);

    canvas.restore();
    canvas.drawRect(40, 0, 140, 100, paint);
}

有个抱歉的地方:我不太请求onDraw每次被回调的Canvas对象是否同一个(汗颜,暂时对draw流程没有进行一个深入理解)


多重嵌套

这个就耳熟能详了。之所以要规避他的原因:比如ViewGroup中有个Button放大了两倍,不仅要触发draw,measure和layout也必须重新进行。

一般解决的手段:很多。。。这个没啥好说的,主要看自己写布局的经验了,写得多了这都不是事儿

还有就是通过自定义控件解决嵌套,比如你可以看看我自定义的BottomBar控件,仅需要一个View:

https://blog.****.net/qq_36523667/article/details/79506043