性能优化之View渲染

在这里插入图片描述
首先我们需要知道以下几点

1 view的基本绘制流程(ViewGroup和View)

2 view的重复绘制原因

3 怎么减少重复绘制

View的基本绘制流程

 做过Android开发的同学都知道,View绘制分为三个阶段:测量、布局和绘制。
    1. 测量即measure阶段:测量主要用到measureSpec这个类,其实是一个32位的int值,其中高2位表示view的测量模式,低30位表示view测量大小,两者共同组合成了view的大小,之所以这么做,是采用位运算可以提高效率,每个view的大小实际上是通过自身视图和父视图决定的。
    2. layout即摆放位置阶段:为整个view树上的view摆放位置
    3.draw阶段:根据前两个阶段得到的参数值,用paint在cances将视图显示在屏幕上。

这里摘抄网上的一张绘制流程图:
在这里插入图片描述

从图中可以出看出当一个页面显示出来时,绘制流程是从performTraversals()方法开始的,这边又涉及到了view的层级关系,再放张图
在这里插入图片描述
当一个Activity创建时,会将一个window和activity关联,所以window的数量和activity是一致的,该处的window即phoneWindow,是window的唯一子类,并且还会创建一个DecoView和ViewRootImpl,两者建立联系,再从ViewRootImpl的performTraversals()开始绘制,该方法会调用performMeasure() 进行测量子view,一开始是顶层viewGroup,然后依次调用到view,再到viewGroup,如此反复,就完成了一个view的绘制。

调用结束performMeasure(),会依次再调用performLayout(),performDraw()

三者主要作用如下

meausure过程:

主要负责测量,如果单个View,直接measuere测量,如果是viewGroup,需要重写onMeasure方法,对子视图遍历测量

layout过程:

在View视图坐标下(x轴朝右,y轴朝下),根据left,top,right,bottom进行位置的摆放,如果是viewGroup,同样需要遍历摆放

draw过程:

绘制背景

如果视图有渐变,做一些初始化工作

绘制视图本身,即调用onDraw()方法,改方法是个空方法,如果是ViewGroup,无需实现该方法,因为容器是有多个子view组成的,所以只需要遍历ViewGroup,让子view完成自己绘制即可

如果需要,开始绘制渐变框

绘制滚动条

View的重复绘制原因以及优化

我们知道,Android系统是每隔16ms发送一次信号,进行刷新UI操作,因此我们必须在16ms之内将页面绘制完成,从而保证页面流畅

通过上面view绘制流程的分享,view绘制优化分为内部和外部。

内部优化:
即view自身绘制花费的时间,绘制流程我们无法干预,但是我们可以减少内部绘制的时间,如下图

在这里插入图片描述
外部优化
在这里插入图片描述
其实平时我们平时做的比较多的是外部优化,比如需要将一个TextView和ImgView一起显示时,无需用一个layout将两个view组合包在一起,可以考虑使用TextView的drawRight属性设置图片

具体见下图

在这里插入图片描述
划重点

1.布局嵌套过于复杂

尽可能的使用Relativelayout来减少层级,使View趋于扁平化

在Linearlayout和RelativeLayout两次深度差不多的情况下使用LinearLayout,因为Reltive由于存在依赖关系,需要测量两次,而LinearLatout存在orientation属性

灵活使用merge,include标签

层级特别深时,尽量少使用权重wight,因为也会导致二次测量

选用合适的布局可以借鉴下图

在这里插入图片描述

2.VIew的频繁渲染

频繁动态的改变宽高,调用setlayoutParams会执行requeatlayout,导致频繁绘制

当需要刷新UI时,如果不需要重新测量时,UI线程直接使用invalidate,非UI线程使用postinvalidate,而不要使用requestLayout,因为该方法会重新走一遍绘制流程

使用viewStub进行懒加载

3.UI进行网络操作,4.0以后已经不允许

UI刷新时异步进行,使用handler

4.代码逻辑冗余复杂,例如多层遍历

可以使用合适的数据结构,例如接口返回字段是map,并且需要排序时,可以使用TreeMap接收,减少排序遍历

5.频繁触发gc,影响页面渲染,因为gc线程优先级高于UI线程

不要频繁生成对象,比如字符串拼接时,尽量使用StringBuilder操作,不要进行+号拼接字符串

6.View过度绘制

总结:View绘制优化是性能优化中重要的一环,当业务越来越庞大,页面愈加复杂时,尤其需要进行view绘制的性能优化

在这里插入图片描述
更精彩内容,大家可以关注我的微信公众号
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值