UI优化<下>
ui渲染测量
测试工具: Profile GPU Rendeing 和 Show GPU Overdraw ,定位方法可以参考官方文档,检查GPU渲染速度和过度绘制
问题定位工具可以使用 Systrace 和 Tracer for OpenGL ES,具体可以参考官方文档:渲染速度慢
适用于自动化测试场景的测试方式(自己加的标题)
虽然图形化界面工具非常好用,但是难以用在自动化测试场景,以下测量方式可以用于自动化测试:
gfxinfo
gfxinfo 可以输出包含各个阶段发生的动画以及帧相关的性能信息,以及渲染相关的内存和View hierachy 信息,命令如下:
adb shell dumpsys gfxinfo
在Android 6.0 之后,gxfinfo 命令新增了 framestats 参数,可以拿到最近120帧每个绘制阶段的耗时信息:
adb shell dumpsys gfxinfo
framestats
SurfaceFlinger
除了耗时,还需要关心渲染使用的内存,4.1以后每个 Surface 都会有 3个 Graphic Buffer,那如何查看 Graphic Buffer 占用的内存,可以通过如下命令查看相应信息:
adb shell dumpsys SurfaceFlinger
这部分内存大小和 屏幕分辨率,以及Surface的个数有关。
UI优化的常用手段
我们的目标是实现app的帧率达到 60fps,意味着所有操作要在 16.7 ms 内完成,这期间要做的事情如下所示:
我们优化,就是拆解渲染的各个阶段耗时,找到瓶颈,加以优化。ui优化的方法如下:
1、尽量使用硬件加速。
硬件加速绘制的性能是远远高于软件绘制的,所以ui优化第一个手段应该尽量使用硬件加速。但是有些api不支持硬件加速,这个需要注意,比如 渐变、磨砂、圆角等,它们的渲染性能比较低。
2、View 的创建优化
View 的创建在UI线程,对于复杂的界面,这部分耗时不容忽视。View 的创建过程中,会包括xml的读取io,解析xml 以及生成对象的时间(Framework会大量使用反射)
因此建议:
1、使用代码创建view 对象缺点是不能直接预览
2、提前创建、异步创建
3、View 重用(模仿ListView、RecyclerView,不过重用要注意先清空状态)。
如果异步创建,那么会导致系统抛出异常。这时候,我们可以通过非常取巧的方式来异步创建ui:先把线程的Looper的MessageQueue替换成Looper的Queue:
要注意的是,在创建完成view之后,需要把线程的Looper恢复成原来的。
3、measure/layout 优化
这两部分也是在ui线程执行的,一般的优化方法有:
- 减少UI布局层次
- 优化layout开销。尽量不要使用 RelativeLayout 和 weighted LinearLayout ,它们开销很大,建议使用 ConstranLayout
- 背景优化。尽量不要重复设置背景,尤其注意的是主题背景,theme默认会是一个纯色背景,如果我们自定义了界面背景,那么主题背景对我们来说是无用的,由于主题背景是设置在DecorView 中的,所以会带来重复绘制,也会带来绘制性能损耗。
4、UI优化进阶
可以采用flutter