Android 开发常用性能优化工具总结

目录

    • systrace
      • Systrace是什么?可以分析哪些问题?
      • 启动
    • perfetto
      • 什么是Perfetto?
      • Perfetto和Systrace的关系?
    • Profile
      • CPU
      • Memory
    • WinScope--跟踪窗口转换
    • Layout Inspector
    • UiAutomatorViewer
    • hierarchyviewer
    • Lint
    • Tencent/matrix
    • 开发者选项
      • 显示面(surface)更新
      • 动画时长缩放
      • 显示布局边界
      • 调试GPU过度绘制
      • GPU渲染模式分析
      • 严格模式


systrace

Systrace是什么?可以分析哪些问题?

Systrace是Android 4.1引入的基于ftrace的性能分析工具,通过在系统各个关键调用位置添加trace埋点 来分析系统调用耗时等问题

启动

  1. 通过DDMS启动:
    由于现在新版本的Android Studio已经不内置DDMS,所以可以通过命令行的方式启动:
    首先进入如下目录Android/Sdk/tools
    启动Monitor.sh文件,进入到DDMS界

Android 开发常用性能优化工具总结_第1张图片

在右侧选择需要同时监听的进程
这个选项可以开启指定包名App中自定义Trace Label的Trace功能。也就是说,如果你在代码中使用了Trace.beginSection(“tag”); Trace.endSection; 默认情况下,你的这些代码是不会生效的,因此,这个选项一定要开启,开启之后,就能在生成的Systrace文件中看到自己在当前进程添加的自定义trace。

然后点击左上角右侧的按钮并进行相关配置

Android 开发常用性能优化工具总结_第2张图片

点击左上角按钮,出来右边选项框,上面配置文件名、持续时长、buffer大小、调试的应用程序等
具体如何配置我们会在之后细讲

Android 开发常用性能优化工具总结_第3张图片

然后点击ok就开始抓trace了,这时候你就可以在这段时间进行操作,以便相关进程能走到你需要测试的逻辑,抓到正确的trace

Android 开发常用性能优化工具总结_第4张图片

  1. 通过命令行启动
    首先cd到如下目录:Android/Sdk/platform-tools/systrace
    终端运行systrace.py文件并添加相关配置,通过-option(参数) value(值)进行配置
    具体可选参数如下:
option(参数) value(值)
-o < FILE > output 指定trace数据文件的输出路径,如果不指定就是当前目录的trace.html
-t N, –time=N 执行时间,默认5s。绝对不要把时间设的太短导致你操作没完Trace就跑完了,分析数据就基本无效了
-b N, –buf-size=N< /td > buffer大小(单位kB),用于限制trace总大小,默认无上限
-a < APP_NAME>,–app=< APP_NAME> 这个选项可以开启指定包名App中自定义Trace Label的Trace功能。也就是说,如果你在代码中使用了Trace.beginSection(“tag”), Trace.endSection;默认情况下,你的这些代码是不会生效的,因此,这个选项一定要开启
-l, –list-categories 这个用来列出你分析的那个手机系统支持的Trace模块,一般来说,高版本的支持的模块更多
-e < DEVICE_SERIAL>,–serial=< DEVICE_SERIAL> 指定设备,在特定连接设备上进行跟踪,由设备序列号标识 。
–from-file=< FROM_FILE> 从Trace文件中加载
-k < KFUNCS>,–ktrace=< KFUNCS> 追踪kernel函数,用逗号分隔

除了这些参数之外,还可以添加自己想要监听的类别或者模块(以下列出常用的模块):

模块 含义
gfx Graphic系统的相关信息
input input
view View绘制相关信息
wm Window Manager
am Activity Manager
sm Sync Manager
app Application
res Resource Loading
sched CPU调度的信息
sync Synchronization

命令行启动trace示例:

python systrace.py gfx input view wm am app res sched sync -b 10240 -t 5 -a com.android.recentspsp -o /media/caiqiwei/internal/mytrace.html

需要注意的点是,在命令行启动时,会有几秒钟的延时,当终端出现Starting tracing时,才表示开始正式抓取trace了

Android 开发常用性能优化工具总结_第5张图片

当出现Tracing completed. Collecting output...时,表示trace已经抓取完毕了,这时cd到我们之前的output目录下,通过chrome浏览器(目前不支持firefox等其它浏览器)打开生成的html文件就可以查看我们抓取的trace文件了

Android 开发常用性能优化工具总结_第6张图片

操作方式是:
w:放大
s:缩小
a:左移
d:右移
1:箭头工具:用于选定目标:选择后会在底部显示当前所选目标的详细信息
4:范围选择工具:用于选取某一范围,可在顶部显示当前范围的时间(ms),并高亮显示
f:快捷选取当前选定目标并居中
m:快速选取当前选定目标并框选范围(个人觉得在有些情况下可以代替 4(范围选择工具)并更加精确)
顶部右侧有工具框及搜索定位框:

在这里插入图片描述

如何查看trace文件:
左侧框为进程名或模块名,点击可展开,查看进程或模块所包含的各个线程调度信息

Android 开发常用性能优化工具总结_第7张图片

最顶部会标记显示运行时间有问题的帧,也就是Alert帧:Android 开发常用性能优化工具总结_第8张图片

点击标记会在底部显示详细信息,并高亮显示对应的帧
Android 开发常用性能优化工具总结_第9张图片

点击空白区域之后发现当前帧确实是处于一个红色的警示显示状态:
Running为总共运行的时间
runnable为可运行但未拿到cpu时间片的等待运行时间
sleep为睡眠时间
正常来说:
当running时间过长的话,我们需要考虑当前帧是否在主线程做了太多的耗时操作
当runnable时间过长的话,需要考虑是否是当前进程内进行了一些跨进程调用之类的行为
当sleep时间过长的话,需要考虑是否是当前进程的调度优先级不够,拿不到cpu时间片

Android 开发常用性能优化工具总结_第10张图片

我们点击当前问题帧的F标志,可以直接高亮显示应用在当前帧所做所有行为
Android 开发常用性能优化工具总结_第11张图片

systrace中会显示三种颜色的帧,绿色代表正常的帧,(即在60hz屏幕上运行时间小于16.6ms,在90hz屏幕上运行时间小于11.1ms,以此类推),黄色和红色的帧均超过规定一帧的时间,红色比黄色更加严重。
如何查看当前设备每一个VSync帧到来的时间?
其实在systrace中已经有显示,可以看到上图中有一个一个的斑马纹,可以通过顶部右侧工具箱中View Options的Highlight VSync开启关闭
在这里插入图片描述

每一个斑马纹其实就代表一个VSync帧(灰色和白色都代表一个VSync帧),我们也可以通过SurfaceFlinger模块的VSync-app来查看
在这里插入图片描述

可以看到VSYNC-app在每一次波峰(数值1)和波谷(数值0)到来时,即是VSync信号到来时,但我们还看到这里还有一个VSync-sf且相对于VSYNC-app有一个offset偏移。
简单解释一下,这个也是VSync信号,不过是基于SurfaceFlinger的VSync信号。
我们知道,应用在每一帧做的事有如下:

  1. 首先在主线程处理doFrame逻辑,在doFrame中会处理input事件、animation动画、performTraversal调用(也就是measure、layout、draw行为)
  2. 完成之后会将数据同步到RenderThread线程并dequeueBuffer从buffer队列中申请buffer进行渲染,完成后通过queueBuffer将渲染完成的buffer入队。

而SurfaceFlinger在VSync信号到来之后一帧的行为如下:
3. 从每一个应用的buffer队列中取出上一帧(正常来说为上一帧,但其实可能为上上帧 等)渲染好的buffer,然后根据layer大小将所有buffer进行合成

其实每一次VSync信号到来时,会同时通知app和SurfaceFlinger,app端接收到VSync信号时会进行当前帧的buffer渲染,而SurfaceFlinger收到VSync信号时,会从各个app的buffer队列中取出渲染完成待合成的buffer进行合成。
而引入offset机制的意义是,如果在app收到VSync信号进行渲染和SurfaceFlinger收到VSync信号进行合成的offset间隔中,app完成了buffer的渲染,那么SurfaceFlinger就可以在当前帧拿到已经渲染好的buffer,保证用户可以更快看到当前buffer
可以看到,我的机器其实就有一个VSync Offset
(6fps校准)

往下则是cpu调度的相关信息
在这里插入图片描述

可以看到当前在每个核上的进程调度信息
点开之后可以看到底部的详细信息,包括:在当前cpu核的当前时间片上运行的进程、线程、运行时间等
在这里插入图片描述

  • Systrace 是平台提供的一款工具,用于记录短期内的设备活动。该工具会生成一份报告,其中汇总了 Android 内核中的数据,例如 CPU 调度程序、磁盘活动和应用线程。这份报告可帮助您了解如何以最佳方式改善应用或游戏的性能。
  • Systrace报告提供了 Android 设备在给定时间段内的系统进程的总体情况,还会检查所捕获的跟踪信息,以突出显示它所观察到的问题(例如界面卡顿或耗电量高)。
  • 在解决应用中与性能相关的错误(例如启动速度慢、转换速度慢或界面卡顿)时,录制跟踪记录特别有用。

perfetto

什么是Perfetto?

Perfetto 是 Android 10 中引入的全新平台级跟踪工具。这是适用于 Android、Linux 和 Chrome 的更加通用和复杂的开源跟踪项目。与 Systrace 不同,它提供数据源超集,可让您以 protobuf 编码的二进制流形式记录任意长度的跟踪记录。您可以在 Perfetto 界面中打开这些跟踪记录。

Perfetto和Systrace的关系?

  • 在 Perfetto 界面中打开 Perfetto 文件和 Systrace 文件。在 Perfetto 界面中使用旧版 Systrace 查看器打开 Systrace 文件(使用 Open with legacy UI 链接)。
  • 使用 traceconv 工具将 Perfetto 跟踪记录转换为旧版 Systrace 文本格式。
  • Systrace 和 Perfetto 不会收集有关应用进程中代码执行情况的详细信息。如需详细了解您的应用正在执行哪些方法及其占用了多少 CPU 资源,请使用CPU Profiler。

启动方式:
Perfetto是基于Android 9(P)起可用的平台级跟踪工具,但仅从Android 11(R)起默认启用。在Android 9(P)和10(Q)上,我们首先需要开启traced和traced_probes这两个进程,才能使用Perfetto来抓取数据,可通过命令行来开启手机的这两个进程

# Needed only on Android 9 (P) and 10 (Q) on non-Pixel phones.
adb shell setprop persist.traced.enable 1

开启之后我们就可以通过perfetto来抓取相关的信息了
目前建议通过chrome浏览器在Perfetto 界面进行操作,方便快捷且可操作性强

首先进入界面后,左边是工具栏,右边是信息栏
Android 开发常用性能优化工具总结_第12张图片

可以看到:
Open trace file是直接打开一个pftrace文件
Open with legacy UI是打开一个pftrace文件的同时将其转换为旧版Systrace
Record new trace则是在线录制一个trace文件

选择在线录制,则跳转到配置界面
顶部可以选择当前想要抓取trace的设备
Recording settings用于配置录制模式、缓存大小、录制时间
Android 开发常用性能优化工具总结_第13张图片

Trace command用于同步生成当前配置的命令行,我们可以直接将其粘贴到终端,通过命令行启动
Android 开发常用性能优化工具总结_第14张图片

probes栏则是其它的一些配置(CPU、GPU、Power等等)
Android 开发常用性能优化工具总结_第15张图片

而我们之前systrace里配置的那些模块,已经移到了Android apps & svcs中
Android 开发常用性能优化工具总结_第16张图片

相较于systrace,perfetto不会直接把VSync帧在图形界面标注出来,所以我们第一步最好是直接找到SurfaceFlinger进程的VSYNC-app数据,并钉在顶部,方便我们能分析出app每一帧的运行时间
Android 开发常用性能优化工具总结_第17张图片

而且同样的,perfetto也不会直接高亮显示出应用的问题帧,而需要你通过应用主线程和RenderThread线程配合SurfaceFlinger的VSYNC-app数据配合分析出当前应用的问题帧

这里有一个比较取巧的小方法,我们可以将trace文件在新版的perfetto打开的同时,通过perfetto提供的legace UI,转换成老版的systrace
通过在systrace中先找到问题帧,再在perfetto中进行细致分析
Android 开发常用性能优化工具总结_第18张图片

Android 开发常用性能优化工具总结_第19张图片

perfetto还提供基于SQLite的查询和分析数据的能力,具体可查看这篇文档:
https://perfetto.dev/docs/quickstart/trace-analysis

Profile

TraceView是Android平台配备一个很好的性能分析工具,它可以通过图形化的方式让我们了解我们要跟踪的程序的性能,并且能具体到方法。
Android 开发常用性能优化工具总结_第20张图片

首先点击上面的Profile按钮
Android 开发常用性能优化工具总结_第21张图片

CPU

Android 开发常用性能优化工具总结_第22张图片

Android 开发常用性能优化工具总结_第23张图片

Android 开发常用性能优化工具总结_第24张图片

Summary Top Down Flame Chart Bottom Up
Trace总时长以及最耗时的十个方法排行,没什么作用 从上到下对最耗时的方法进行排行(不涉及方法调用),可以快速找到时间段中最耗时的方法 最耗时单个方法的倒火焰图,可以分析最耗时方法之所以耗时的原因,但个人感觉没有左侧的线程调用方法火焰图信息全面 从上到下对最耗时的方法进行排行(涉及方法调用),和Summary中显示的十个方法是一个排行榜,一般都是位于单个方法内,或集中在几个方法中
Android 开发常用性能优化工具总结_第25张图片 Android 开发常用性能优化工具总结_第26张图片 Android 开发常用性能优化工具总结_第27张图片 Android 开发常用性能优化工具总结_第28张图片

Memory

Android 开发常用性能优化工具总结_第29张图片

Android 开发常用性能优化工具总结_第30张图片

WinScope–跟踪窗口转换

WinScope 提供了用于在窗口转换期间和转换后记录和分析 WindowManager 状态和 SurfaceFlinger 状态的基础架构和工具。WinScope 将所有相关的系统服务状态记录在一个跟踪文件中,您可以使用该文件重现并逐步查看转换。

相关详细介绍可查看Google官方网站: Tracing Window Transitions

Layout Inspector

通过在Android Studio -> Tools -> Layout Inspector打开:
勾选Show all processes可显示所有进程
Android 开发常用性能优化工具总结_第31张图片

这里有一个问题是在有些时候会出现无法找到adb或adb被占用的问题
adb disconnect一下并在开发者选项中关闭打开一下usb调试就好了

Android 开发常用性能优化工具总结_第32张图片

  • 左侧为当前window视图树,可通过关键字搜索指定View(类名、id)
  • 中间部分显示当前视图缩略图,通过点击相关位置可在左侧精确定位到View(此处有一个问题是:如果上层有其它View覆盖在上面,则会选中上层的View,这时在左侧将选择的View右键菜单去掉Show Layout Bounds勾选,一层一层去掉,直到找到自己所需要的View)
  • 右侧显示当前选中View的详细信息,相较于hierarchyviewer,Layout Inspector的属性栏会显示更多的View相关信息(主要是View的属性信息:Clickable、Enable等属性)

但是Android Studio的Layout Inspector有一个问题是,对于视图树较为复杂的Window,抓取时间超时(默认20s),导致无法抓取当前的视图树,以及Android Studio 4.0引入的实时Layout Inspector导致的部分问题。

对此,网上也有相关解决办法,也就是将超时的默认20s时长修改更长,保证能够在限定时间内解析较为复杂的视图树。具体可查看这篇博客:
Android Studio LayoutInspector 超时错误解决

UiAutomatorViewer

命令行启动:
通过命令行打开位于Sdk/tools/bin/下的uiautomatorviewer.sh文件
Android 开发常用性能优化工具总结_第33张图片

点击左上工具栏的第二个按钮可以截取当前手机或虚拟机的界面进行分析
Android 开发常用性能优化工具总结_第34张图片

但相对于上文中 “加强版” 的Layout Inspector来说,还是八行:
首先,只能解析出一些原生基础View/ViewGroup,无法像Layout Inspector一样拿到精确的类名,其次解析出的属性太少,唯一的优势就是快,但没啥用

hierarchyviewer

命令行启动
直接命令行输入:

hierarchyviewer

连接adb之后即可看到所有的window列表
Android 开发常用性能优化工具总结_第35张图片

点击其中一个就可以加载出当前window的View视图树
Android 开发常用性能优化工具总结_第36张图片

以横向树状图的形式在左侧展示当前window所有的View视图结构
每一个节点显示当前View的类名、View Id(View.getId())
点击其中一个View会直接显示其本身和子View的视图缩略图以及当前View的measure、layout、draw所耗时间
右侧分别显示:

  1. 整体树状图概览以及当前所选View在整体中的位置
  2. 当前View的其它属性(各种宽高、状态值、margin padding、text等)
  3. 当前View在视图中显示的位置(通过 Show Extras开启)

hierarchyviewer相对于新版的Layout Inspector还有一个比较有用的属性是:统计并比较当前View各个子View的测量、布局、绘制时长
通过顶部工具栏的Profile Node打开:

  1. 首先选择一个带有多个子View的父View
  2. 其次点击工具栏上的Profile Node开关,此时每个子View底部都会有三个彩色圆点
    Android 开发常用性能优化工具总结_第37张图片

圆点有三种颜色(绿、黄、红),分别对应视图的measure、layout、draw的时长
Android 开发常用性能优化工具总结_第38张图片

此为官方给出的对于颜色的解释(说实话,绿色和黄色的含义比较模糊)

  • 绿色表示视图的渲染速度至少比一半的其他视图快。
  • 黄色表示视图渲染速度比其他视图中渲染速度最慢的那一半快。
  • 红色表示视图是渲染速度最慢的那一半视图之一。

Green means the view renders faster than at least half of the other views.
Yellow means the view renders faster than the bottom half of the other views.
Red means the view is among the slowest half of views.

如下是官方给出的分析建议:
Hierarchy Viewer 可测量每个节点相对于同级视图的性能,因此分析结果中总是有红色节点(除非所有视图以完全相同的方式执行),并且这并不一定意味着红色节点就是表现不佳(只不过它是本地视图组中最慢的视图而已)。
Hierarchy Viewer 会栅格化您的布局以获取时间信息。栅格化是获取高级基元(如圆形或矢量字体)并将其转换为屏幕上的像素的过程。栅格化通常由设备上的 GPU 完成,但对于软件栅格化,渲染是使用普通软件在 CPU 上完成的。这意味着绝对报告时间相对于彼此是正确的,但会随着设备和开发计算机上的不断变化的总体 CPU 工作负载而变化。因此,它不能反映设备上的实际性能速度,您应该进行多次分析以了解平均测量结果。
如果应用的运行速度出乎意料地慢,则红色节点可能有问题。在相对设置中,总有一个最慢的节点;只需确保它是您预期的节点即可。以下示例说明了如何解读红色圆点。

  • 查找叶节点中的红色圆点或仅包含少数子级的视图组。这可能会找到问题所在。应用的运行速度可能并不缓慢,或者在设备上的运行速度并不慢,但您需要注意这个圆点为何显示为红色。 Systrace 或 Traceview 可为您提供更多信息。
  • 如果您有一个包含许多子级的视图组和一个红色测量阶段,请查看相应子级以了解它们的执行情况。
  • 带有黄色甚或红色圆点的视图在设备上的执行速度可能并不慢。这正是实际数字的用武之地。 Systrace 或 Traceview 可为您提供更多信息。
  • 如果层次结构的根视图具有红色测量阶段、红色布局阶段和黄色绘制阶段,那这就是一个比较典型的情况,因为它是所有其他视图的父级,并且只有在子级完成之后其布局才会完成。
  • 如果具有 20 个以上视图的树中的某个叶节点包含红色绘制阶段,则表示存在问题。请检查 onDraw() 方法中是否有不应存在的代码。

Lint

Android Lint 是 SDK Tools 16(ADT 16)开始引入的一个代码扫描工具,通过对代码进行静态分析,可以帮助开发者发现代码质量问题和提出一些改进建议。除了检查 Android 项目源码中潜在的错误,对于代码的正确性、安全性、性能、易用性、便利性和国际化方面也会作出检查。
Android Lint 作为项目的代码检测工具,是因为它具有以下几个特性:

  • 已经被集成到 Android Studio,使用方便。
  • 能在编写代码时实时反馈出潜在的问题。
  • 可以自定义规则。Android Lint 本身包含大量已经封装好的接口,能提供丰富的代码信息,开发者可以基于这些信息进行自定义规则的编写。

启动:
工具栏 -> Analyze -> Inspect Code
Android 开发常用性能优化工具总结_第39张图片

这里可以选择需要扫描的路径,然后进行扫描
扫描完成后生成扫描结果
Android 开发常用性能优化工具总结_第40张图片

可以看到,有很多条目,但其实不是所有的条目都是有用的
我们主要看Android Lint下的相关条目
Android 开发常用性能优化工具总结_第41张图片

如上图所展示的,Android Lint 对检查的结果进行了分类,同一个规则(issue)下的问题会聚合,其中针对 Android 的规则类别会在分类前说明是 Android 相关的,主要是六类:

  • Accessibility 无障碍,例如 ImageView 缺少contentDescription 描述,String 编码字符串等问题。
  • Correctness 正确性
  • Internationalization 国际化,如字符缺少翻译等问题。
  • Performance 性能,例如在 onMeasure、onDraw 中执行 new,内存泄露,产生了冗余的资源,xml 结构冗余等。
  • Security 安全性,例如没有使用 HTTPS 连接 Gradle,AndroidManifest 中的权限问题等。
  • Usability 易用性,例如缺少某些倍数的切图,重复图标等。

后面其他的结果条目则是针对 Java 语法的问题

我们点开Performance条目下的性能问题
Android 开发常用性能优化工具总结_第42张图片

里面也是很多条目
例如:
用< merge >标签替代相关FrameLayout
SparseArray替代HashMap 等

我们可以以此作为参考,根据实际情况进行修改

详细的介绍及自定义Lint相关操作可以查看这篇文章,很细致

Tencent/matrix

Matrix 是一款微信研发并日常使用的应用性能接入框架,支持iOS, macOS和Android。 Matrix 通过接入各种性能监控方案,对性能监控项的异常数据进行采集和分析,输出相应的问题分析、定位与优化建议,从而帮助开发者开发出更高质量的应用。

matrix

开发者选项

显示面(surface)更新

可以有效查看到操作时界面的surface更新区域
不支持在 Docs 外粘贴 block

eg:之前敏感权限和时间胶囊的需求开发的时候,发现手机systemui的耗电剧增,打开Surface更新发现,systemui在每一帧都有surface更新,查找原因是因为敏感权限的需求导致状态栏左侧的时间区域由于呼吸动画的缘故不停做动画,导致整个状态栏每一帧都在更新,严重增加耗电,最后取消了呼吸动画

动画时长缩放

动画相关调试,但目前不支持物理动画的时长缩放(Fling Spring)

显示布局边界

可以粗略查看View的layout情况,但细节方面的数值还需要配合Layout相关工具查看

Android 开发常用性能优化工具总结_第43张图片

调试GPU过度绘制

何为过度绘制?
过度绘制是指系统在渲染单个帧的过程中多次在屏幕上绘制某一个像素。例如,如果我们有若干界面卡片堆叠在一起,每张卡片都会遮盖其下面一张卡片的部分内容。
但是,系统仍然需要绘制堆叠中的卡片被遮盖的部分。这是因为堆叠的卡片是根据 Painter 算法(也就是按从后到前的顺序)来渲染的。按照这种渲染顺序,系统可以将适当的透明度混合应用于阴影之类的半透明对象。
过度绘制通常是不必要的,最好避免。它会浪费 GPU 时间来渲染与用户在屏幕上所见内容无关的像素,进而导致性能问题。

overlap

Android 开发常用性能优化工具总结_第44张图片 Android 开发常用性能优化工具总结_第45张图片

Android 将按如下方式为界面元素着色,以确定过度绘制的次数:
Android 开发常用性能优化工具总结_第46张图片

请注意,这些颜色是半透明的,因此在屏幕上看到的确切颜色取决于界面内容。
事实上,有些过度绘制是不可避免的。在优化应用的界面时,应尽量尝试达到大部分显示真彩色或仅有 1 次过度绘制(蓝色)的视觉效果。

默认情况下,布局没有背景,这表示布局本身不会直接渲染任何内容。但是,当布局具有背景时,其有可能会导致过度绘制。 移除不必要的背景可以快速提高渲染性能。不必要的背景可能永远不可见,因为它会被应用在该视图上绘制的任何其他内容完全覆盖。例如,当系统在父视图上绘制子视图时,可能会完全覆盖父视图的背景。

布局优化:
ViewStub、merge、include等

GPU渲染模式分析

Android 开发常用性能优化工具总结_第47张图片

图为某手机任务管理器返回动画渲染条形图

下面是有关输出的几点注意事项:

  • 对于每个可见应用,该工具将显示一个图形。
  • 沿水平轴的每个竖条代表一个帧,每个竖条的高度表示渲染该帧所花的时间(以ms为单位)。
  • 水平绿线表示 16.6ms(60 FPS)/11.1ms(90 FPS)。正常的帧率,代表每个帧的竖条需要保持在此线以下。当竖条超出此线时,可能会使动画出现暂停。
  • 该工具通过加宽对应的竖条并降低透明度来突出显示超出 16ms 阈值的帧。
  • 每个竖条都有与渲染管道中某个阶段对应的彩色区段。区段数因设备的 API 级别不同而异。

下表介绍了使用运行 Android 6.0 及更高版本的设备时分析器输出中竖条的每个区段:
Android 开发常用性能优化工具总结_第48张图片

在这里插入图片描述

在Android6.0之前,柱状图主要为黄色、红色、蓝色(Swap Buffers,Command Issue,Draw)三类。自从安卓6.0之后,玄学曲线进行了改版,增加至8条数据。新版本GPU呈现分析曲线新增加了(Sync&Upload,Measure&LayoutAnimation,Input Handling,Misc/Vsync Delay)五大步骤数据。
(1)Command Issue(红色):表示执行任务的时间,是Android进行2D渲染显示列表的时间,为了将内容绘制到屏幕上,Android需要使用Open GL ES的API接口来绘制显示列表,红色线条越高表示需要绘制的视图更多;比如我们在遇到多张图加载的时候,红色会突然跳的很高,此时滑动页面也就不流畅了,要等几秒图片才能加载出来,并不是卡住。
(2)Swap Buffers(黄色):表示处理任务的时间,即CPU等待GPU完成任务的时间,线条越高,表示GPU做的事情越多。若橙色部分过高,说明GPU目前过于忙碌。
(3)Draw(蓝色):表示测量和绘制视图列表所需要的时间,蓝色线条越高表示每一帧需要更新很多视图,或者View的onDraw方法中做了耗时操作。它越长说明当前视图比较复杂或者无效需要重绘,表现为卡顿。
理想的流畅状态是三色都低于绿线以下。
(4)Sync & Upload(浅蓝色):表示的是准备当前界面上有待绘制的图片所耗费的时间,为了减少该段区域的执行时间,我们可以减少屏幕上的图片数量或者是缩小图片的大小。
下面这几种统称为绿色,随着后面标注的数字颜色逐渐加深。
(5) Measure/Layout(绿色1)表示布局的onMeasure与onLayout所花费的时间,一旦时间过长,就需要仔细检查自己的布局是不是存在严重的性能问题。
(6)Animation(绿色2):表示计算执行动画所需要花费的时间,包含的动画有ObjectAnimator,ViewPropertyAnimator,Transition等等。一旦这里的执行时间过长,就需要检查是不是使用了非官方的动画工具或者是检查动画执行的过程中是不是触发了读写操作等等。
(7)Input Handling(绿色3):表示系统处理输入事件所耗费的时间,粗略等于对事件处理方法所执行的时间。一旦执行时间过长,意味着在处理用户的输入事件的地方执行了复杂的操作。
(8) Misc Time/Vsync Delay(绿色4):表示在主线程执行了太多的任务,导致UI渲染跟不上vSync的信号而出现掉帧的情况。
总结一下:
红色/黄色:从布局构建角度去考虑。优化:否减少视图层级、减少无用的背景图、减轻自定义控件复杂度等。
蓝色/浅蓝/各种绿色:从耗时操作角度去考虑。

严格模式

Android Developer关于严格模式的介绍:StrictMode

StrictMode是一个开发人员工具,可以检测到您可能偶然执行的操作并将其引起您的注意,以便您可以对其进行修复。
StrictMode最常用于在应用程序的主线程上捕获意外的磁盘或网络访问,在该主线程上接收UI操作并进行动画处理。使磁盘和网络操作脱离主线程(位于异步线程)可以使应用程序更加顺畅,响应更快。通过使应用程序的主线程保持响应状态,还可以防止向用户显示ANR对话框。
我们一般将StrictMode相关的检测代码放入应用程序组件的Application::onCreate 方法:

public void onCreate() {
     if (DEVELOPER_MODE) {
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .detectDiskWrites()
                 .detectNetwork()   // or .detectAll() for all detectable problems
                 .penaltyLog()
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());
     }
     super.onCreate();
 }

然后在开发者选项中打开严格模式

eg:

android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
        at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:1877)
        at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:286)
        at android.view.SurfaceControl.finalize(SurfaceControl.java:980)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:289)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:276)
        at java.lang.Daemons$Daemon.run(Daemons.java:137)
        at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.Throwable: Explicit termination method 'release' not called
        at dalvik.system.CloseGuard.open(CloseGuard.java:237)
        at android.view.SurfaceControl.<init>(SurfaceControl.java:899)
        at android.view.SurfaceControl.<init>(SurfaceControl.java:79)
        at android.view.SurfaceControl$1.createFromParcel(SurfaceControl.java:965)
        at android.view.SurfaceControl$1.createFromParcel(SurfaceControl.java:963)
        at android.os.Parcel.readParcelable(Parcel.java:2973)
        at android.view.RemoteAnimationTarget.<init>(RemoteAnimationTarget.java:188)
        at android.view.RemoteAnimationTarget$1.createFromParcel(RemoteAnimationTarget.java:261)
        at android.view.RemoteAnimationTarget$1.createFromParcel(RemoteAnimationTarget.java:259)
        at android.os.Parcel.readTypedObject(Parcel.java:2811)
        at android.os.Parcel.createTypedArray(Parcel.java:2772)
        at android.view.IRemoteAnimationRunner$Stub.onTransact(IRemoteAnimationRunner.java:103)
        at android.os.Binder.execTransactInternal(Binder.java:1132)
        at android.os.Binder.execTransact(Binder.java:1014)

你可能感兴趣的:(Android,性能优化,android,性能优化,android,studio)