其他分享
首页 > 其他分享> > Android性能优化:绘制优化,Android开发了解这些自然无惧面试

Android性能优化:绘制优化,Android开发了解这些自然无惧面试

作者:互联网

当第一帧数据没有及时处理时,为什么CPU不能在第二个16ms处即VSync到来就开始工作呢?

因为只有两个Buffer;所以4.1版本后,出现了第三个缓冲区:Triple Buffer。它利用CPU/GPU的空闲等待时间提前准备好数据,并不一定会使用

注意

除非必要,大部分情况下只是用到双缓冲。而且,缓冲区并不是越多越好,要做到平衡到最佳效果。

Google做了这么多的优化,为什么实际开发中应用还存在卡顿现象?

因为 VSync 中断处理的线程优先级一定要最高,否则即使接收到VSync中断,不能及时处理,也是徒劳无功。

Choreographer的作用是什么?

当收到VSYNC信号时,调用用户设置的回调函数。回调类型的优先级从高到低为CALLBACK_INPUT、CALLBACK_ANIMATION、CALLBACK_TRAVERSAL

3、卡顿的根本原因


二、性能分析工具

========================================================================

Android常用的绘制优化工具一般有如下几种:

这里我们来讲解后面三种分析工具。

1、卡顿检测工具Profile GPU Rendering


它是Android手机上自带的一个辅助工具,打开Profile GPU Rendering后可以看到实时刷新的彩色图,其中每一根竖线表示一帧,由多个颜色组成。

Android M之前

在Android M版本之前,每一条柱状图都由红、黄、蓝、紫组成,分别对应每一帧在不同阶段的实际耗时不同颜色的解释如下:

Android M及之后

并且,从Android M开始变成了渲染八步骤:

1、橙色-Swap Buffers

表示GPU处理任务的时间。

2、红色-Command Issue

进行2D渲染显示列表的时间,越高表示需要绘制的视图越多。

3、浅蓝-Sync&Upload

准备有待绘制的图片所耗费的时间,越高表示图片数量越多或图片越大。

4、深蓝-Draw

测量和绘制视图所需的时间,越高表示视图越多或onDraw方法有耗时操作。

5、一级绿-Measure/Layout

onMeasure与onLayout所花费的时间。

6、二级绿-Animation

执行动画所需要花费的时间。越高表示使用了非官方动画工具或执行中有读写操作。

7、三级绿-Input Handling

系统处理输入事件所耗费的时间。

8、四级绿-Misc Time/Vsync Delay

主线程执行了太多任务,导致UI渲染跟不上vSync的信号而出现掉帧。

此外,可通过如下 adb命令将具体的渲染耗时输出到日志中来分析

adb shell dumpsys gfxinfo com..

复制代码

2、TraceView


它主要用来分析函数的调用过程,可以对Android的应用程序以及Framework层代码进行性能分析。

使用TraceView查看耗时,主要关注Calls + Recur Calls / Total和(该方法调用次数+递归次数)和Cpu Time / Call(该方法耗时)这两个值,然后优化这些方法的逻辑和调用次数,减少耗时

注意

RealTime(实际时长)的实际执行时间要比CPU Time要长,因为它包括了CPU的上下文切换、阻塞、GC等时间消耗。

3、Systrace UI性能分析


Systrace是Android 4.1及以上版本提供的性能数据采样和分析工具,它的主要作用可以归结为如下两点:

1、Systrace使用方法

使用事项如下:

一般我们使用命令行来得到输出的html表单,在4.3版本及以上可以省略设置跟踪类别标签来获取默认值。命令如下:

cd android-sdk/platform-tools/systrace

python systrace.py --time=10 -o mynewtrace.html sched gfx view wm

复制代码

其中,常用的几个参数命令如下:

其余标签用法请参见此处

此外,我们可以使用代码插桩的方式,在Android 4.3及以上版本可以使用Trace类的Trace.beginSection()与Trace.endSection()方法来进行追踪。其中需要注意:

2、分析Systrace报告

使用Chrome打开文件后,其中和UI绘制关系最密切的是Alerts和Frame两个数据:

最后,这里再列出在Systrace便于操作的快捷键:

三、布局优化方式

========================================================================

1、减少层级


合理使用RelativeLayout和LinearLayout

RelativeLayout也存在性能低的问题,原因是RelativeLayout会对子View做两次测量。但如果在LinearLayout中有weight属性,也需要进行两次测量,但是因为没有更多的依赖关系,所以仍然会比RelativeLayout的效率高。

注意

由于Android的碎片化程度很高,所以使用RelativeLayout能使构建的布局适应性更强。

合理使用Merge

merge的原理:在Android布局的源码中,如果是Merge标签,那么直接将其中的子元素添加到Merge标签Parent中。

注意

2、提高显示速度


ViewStub是一个轻量级的View,它是一个看不见的,并且不占布局位置,占用资源非常小的视图对象。可以为ViewStub指定一个布局,加载布局时,只有ViewStub会被初始化,然后当ViewStub被设置为可见时,或是调用了ViewStub.inflate()时,ViewStub所指向的布局才会被加载和实例化,然后ViewStub的布局属性都会传给它指向的布局

注意:

3、布局复用


Android的布局复用可以通过 include 标签来实现。

4、小结


最后,下面列出了我平常做布局优化时的一些小技巧:

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

使用Spannable/Html.fromHtml替换多种不同规格文字。

四、避免过度绘制

========================================================================

导致过度绘制的主要原因一般有如下两点:

1、过度绘制检测工具


打开手机开发者选项中的Show GPU Overdraw选项,会有不同的颜色来表示过度绘制次数,依次是无、蓝、绿、淡红、深红,分别对应0-4次过度绘制。

2、如何避免过度绘制


1、布局上的优化

比如:在获取Avatar的图像之后,把ImageView的Background设置为Transparent,只有当图像没有获取到时,才设置对应的Background占位图片。

2、自定义View优化

通过canvas.clipRect()来帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制。并且,它还可以节约CPU和GPU资源,在clipRect区域之外的绘制指令都不会被执行。

在绘制一个单元之前,首先判断该单元的区域是否在Canvas的剪切域内。若不在,直接返回,避免CPU和GPU的计算和渲染工作。

五、合理的刷新机制

=========================================================================

1、减少刷新次数


2、避免后台线程的影响


如通过监听ListView的onScrollStateChanged事件,在滚动时暂停图片下载线程工作,结束后再开始,可以提高ListView的滚动平滑度,RecyclerView同理。

3、缩小刷新区域


如自定义View一般采用invalidate方法刷新,可以使用以下重载方法指定要刷新的区域:

六、提升动画性能

========================================================================

提升动画性能主要从以下三个纬度着手:

1、帧动画


消耗资源最多,效果最差,能不用就不用。

2、补间动画


使用补间动画实现导致View重绘非常频繁,更新DisplayList的次数过多,且有以下缺点:

3、属性动画


相比于补间动画,属性动画重绘明显会少很多,应优先使用。

4、使用硬件加速


1、硬件加速原理

核心类:DisplayList,每一个View对应一个。

在打开硬件渲染后绘制View时,其中执行绘制的draw()方法会把所有绘制命令记录到一个新的显示列表(DisplayList),这个显示列表包含了输出的View层级的绘制代码,但并不是加入到显示列表就立刻执行,当这个ViewTree的DisplayList全都记录完毕后,由OpenGLRender负责将Root View中的DisplayList渲染到屏幕上。而invalidate()方法只是在显示列表中记录和更新显示层级,去标记不需要绘制的View

2、硬件加速控制级别

如果应用程序中只使用了标准View或者Drawable,就可以为整个系统打开硬件加速的全局设置。

标签:动画,ViewStub,无惧,优化,使用,Android,绘制,View
来源: https://blog.csdn.net/m0_64383081/article/details/121731729