Android提供了一些工具可以用来帮助分析你的UI是否存在图形绘制问题,例如执行过多不需要的绘制工作,或执行长时间的GPU操作。

分析GPU呈现速度

GPU呈现模式工具以滚动直方图的形式展现,显示渲染UI窗口每帧所花费的时间,系统的基准时间是于每帧16ms。这个分析工具可以帮助确定GPU在图形绘制过程中各阶段的状态,或过度绘制引起渲染性能降低的情况。

打开 GPU 呈现模式分析

在Android 4.1以上的系统中,需要分析应用的GPU呈现速度时,可以通过两种方式打开 GPU 呈现模式。

  • 在设备上,使能开发者模式,进入 “设置”->"开发者选项",在“监控”栏中点击“GPU呈现模式分析”,然后在弹出窗中选择“在屏幕上显示为条形图”。
  • 使用ADB通过 property 打开

    $ adb shell setprop debug.hwui.profile [true/visual_bars/false]

检查输出

开启GPU呈现模式分析,打开需要跟踪的应用,一些条形图会显示在屏幕下方。Android 6.0(API level 23)中显示如下图,

gpu_profile_1.png

关于输出,一些说明如下,

  • 对于每个可见的应用程序,该工具都会显示一个图形。
  • 沿水平轴的每个柱状图都代表一帧,柱状图的高度代表该帧渲染所花费的时间(以毫秒为单位)。
  • 水平的绿线表示16毫秒。为了达到每秒60帧,每帧柱状图的高度必须保持在此线以下。当柱状图超过该线时,动画中可能会有卡顿。
  • 超过16毫秒阈值的帧通过加宽图形宽度和减少透明度来突出显示。
  • 每个柱状图都有不同彩色组成,这些颜色表示不同的渲染阶段。颜色的数量取决于设备所使用的API level。

下表描述了分析工具运行Android 6.0或更高版本的设备时,柱状图中各颜色代表的意义。

颜色 渲染阶段 描述
橙色 Swap Buffers 表示CPU等待GPU完成工作的时间。如果此线条变高,则表示该应用在GPU上执行了太多工作。
红色 Command Issue 表示Android的2D渲染器向OpenGL发送命令进行绘制及重新绘制显示列表所花费的时间。该条的高度与每个显示列表执行所花费的时间之和成正比,显示列表内容越多,红色条越高。
浅蓝色 Sync & Upload 表示将位图信息上传到GPU中所需的时间。多数时候意味着该应用程序需要花费大量时间来加载大量图形。
蓝色 Draw 表示用于创建和更新视图的显示列表的时间。如果这一部分很高,则可能有很多自定义的视图,或者onDraw方法中有很多工作。
浅绿色 Measure / Layout 表示在视图层次结构中的onLayout和onMeasure回调上花费的时间。意味着视图层次结构需要花费很长时间进行处理。
绿色 Animation 表示运行该帧中全部动画所花费的时间。如果此线条很高,则您的应用可能使用的自定义动画效果不佳,或者由于更新了属性而发生了意外工作。
深绿色 Input Handling 表示应用程序在输入事件回调中执行代码所花费的时间。如果此线条很高,则表明该应用花费了太多时间来处理用户输入。应该考虑将此类处理工作分配到另一个线程。
墨绿色 Misc Time / VSync Delay 表示应用在两个连续的帧之间花费执行时间的时间。如果此线条很高,可能是UI线程中发生了过多的处理,这些处理可以转移到其他线程。

Dump Profile数据

有时我们可能希望获得GPU呈现模式中的数据,用于进行细致的分析,这时可以通过ADB来获取。

  • 使用ADB通过property来打开GPU呈现模式

    $ adb shell setprop debug.hwui.profile true
  • 使用dumpsys获取profile数据。

    $ adb shell dumpsys gfxinfo com.xxxx.xxx

在执行的结果中,可以在“Profile data in ms”下获取profile数据.

gpu_profile_2.png

Draw + Process + Execute = 完整显示一帧 ,这个时间要小于 16ms 才能保证每秒 60 帧。

分析过度绘制

检查过度绘制

过度绘制工具可以帮助开发者检查是否进行了不必要的渲染工作。该工具使用颜色来标识过度绘制,当应用在同一帧内多次绘制同一像素时,就表明发生过度绘制,并使用不同的颜色进行标记。过度绘制表明GPU付出了额外的工作来渲染用户看不见的像素,这样会影响性能,应该尽可能修复。

过度绘制工具可以在开发者选项中打开,设置->开发者选项->调试GPU过度绘制。打开工具后,应用中如果发生过度绘制,会表现类似下图。

gpu_profile_3.png

图中的不同颜色表示像素在一帧内重绘的次数,

  • 真实颜色:未发生重绘。
  • 蓝色:重绘1次。
  • 绿色:重绘2次。
  • 粉色:重绘3次。
  • 红色:重绘4次以及4次以上。

需要注意的时,这些颜色是半透明的,因此您在屏幕上看到的确切颜色取决于UI的内容。有些重绘是不可避免的,因此在调试应用程序的用户界面时,获得大部分真实色彩或仅显示1倍过度绘制(蓝色)的显示效果即可。

减少过度绘制

可以从以下几个方向来减少或消除过度绘制,

  • 去除布局中不必要的背景。
  • 扁平化视图结构。
  • 降低透明度。

默认情况下,布局不具有背景,这意味着它不会直接渲染任何内容。但是当布局存在背景时,它们就有可能导致过度绘制。 删除不必要的背景能快速提高渲染性能。不必要的背景可能永远都不可见,因为应用程序在该视图之上绘制的其他内容可能将其完全覆盖。例如,当系统在顶层绘制子视图时,可能会完全掩盖背景。 想要找出过度绘制原因,需要使用Layout Inspector工具遍历层次结构。在进行这个工作时,注意可以消除的背景,因为它们对用户不可见。如果许多容器共享相同的背景色,则可以消除不必要的背景:您可以将窗口背景设置为应用程序的主要背景色,并在其上方保留所有容器,但不设置背景值。

现代布局可以非常容易的对视图进行堆叠和分层,从而产生精美的设计。但是这样做可能会导致过度绘制,从而降低性能。特别是当每个堆叠的视图对象都不透明时,可见像素和不可见像素都需要在屏幕上进行绘制。 如果遇到此类问题,可以通过优化视图层次结构以减少重叠的UI对象的数量来提高性能。

屏幕上透明像素的渲染(Alpha渲染)也是过度绘制的关键因素。在标准的过度绘制中,系统通过在不透明像素上方绘制不透明像素来完全隐藏现有绘制像素。而在渲染透明对象时,则需要先绘制现有像素,这样才能产生正确的混合效果。诸如透明动画,淡出和阴影之类的视觉效果都涉及某种类型的透明性,因此可以显着地影响过度绘制。在这些情况下,可以通过减少渲染的透明对象的数量来改善过度绘制。例如,在TextView上绘制带有半透明alpha值的黑色文本来获得灰色文本时,也可以直接将文本绘制为灰色,即可获得相同的效果,并具有更好的性能。

参考文档:

Android Developer: Inspect GPU rendering speed and overdraw


戈壁老王
143 声望61 粉丝

做为一个不称职的老年码农,一直疏忽整理笔记,开博记录一下,用来丰富老年生活,