Android应用性能优化最佳实践.2.2 性能分析工具

简介:

2.2 性能分析工具


从前一节可以看到,Android系统在4.1以后从框架上解决了由于系统问题导致的卡顿现象,但在实际的使用过程中,在用户的感受上,卡顿仍然是应用开发中主要面临的问题,而原因从上一节的分析中也知道本质是VSync信号到来时,不能及时处理绘制事件导致,本节先抛出以下两个问题:

1)应用层做了什么会导致VSync事件不能及时处理?

2)卡顿能监控吗?

性能问题并不容易复现,也不好定位,光从几个场景不能完全覆盖所有的问题,因此在做性能优化时,最直接有效的方法,就是尽量复现存在性能问题的场景,并监控此过程中程序的执行流程,如果能够方便地分析程序中函数的调用关系和执行时间,自然也就很容易找出性能瓶颈。

分析问题和确认问题是否解决,都借助了相应的调试工具,比如查看Layout层次的Hierarchy View、Android系统上带的GPU Prof?ile工具和静态代码检查工具Lint等。这些工具对性能优化都起到非常重要的作用。本节将介绍这些工具和另外两个性能优化非常重要的工具:TraceView和Systrace。这两个工具除了在UI上,对于在后面将要讲到的启动优化、动画优化等上都是很重要的工具,可以说大部分的性能分析都离不开这几个工具,接下来学习几个常用的与流畅度优化相关的工具的使用方法,在后面实际的优化方案中也会介绍其他辅助工具。

2.2.1 卡顿检测工具

要做性能优化,就非常有必要借助于一系列辅助工具,Android提供了多个开发辅助工具,在性能调优过程中非常重要,下面介绍几个常用的工具,在后面的具体优化过程中会多次使用到。

我们已经知道,从应用层绘制一个页面(View),主要有三个过程:CPU准备数据→GPU从数据缓存列表获取数据→Display设备绘制,这三个过程的耗时可以通过一个手机开发辅助工具查看:Prof?ile GPU Rendering。Prof?ile GPU Rendering是Android 4.1系统开始提供的一个开发辅助功能,在设置中打开开发者选项,如图2-12所示。

Prof?ile GPU Rendering功能特点如下:

它是一个图形监测工具,能实时反应当前绘制的耗时。

横轴表示时间,纵轴表示每一帧的耗时(单位为ms)。

随着时间推移,从左到右的刷新呈现。

提供了一个标准的耗时,如果高于标准耗时,表示当前这一帧丢失。

如果设置中没有开发者选项,可以通过设置页面中的“关于”选项,单击版本号七次即可打开开发者选项,在后面的章节中还会使用到开发者选项中的其他辅助工具。

打开Prof?ile GPU Rendering后可以看到实时刷新的彩色图,如图2-13所示。每一根竖线表示一帧,由多个颜色组成,不同颜色的解释如下:

图2-12 打开Prof?ile GPU rendering 图2-13 Prof?ile GPU rendering

每一条柱状图都由4种颜色组成:红、黄、蓝、紫,这些线对应每一帧在不同阶段的实际耗时。

蓝色代表测量绘制的时间,它代表需要多长时间去创建和更新DisplayList。在Android中,一个视图在进行渲染之前,它必须被转换成GPU熟悉的格式,简单来说就是几条绘图命令,蓝色就是记录了在屏幕上更新视图需要花费的时间,也可以理解为执行每一个View的onDraw方法,创建或者更新每一个View的Display List对象。在蓝色的线很高时,有可能是因为需要重新绘制,或者自定义视图的onDraw函数处理事情太多。

红色代表执行的时间,这部分是Android进行2D渲染Display List的时间,为了绘制到屏幕上,Android需要使用OpenGl ES的API接口来绘制Display List,这些API有效地将数据发送到GPU,最终在屏幕上显示出来。当红色的线非常高时,可能是由重新提交了视图而导致的。

橙色部分表示处理时间,或者是CPU告诉GPU渲染一帧的地方,这是一个阻塞调用,因为CPU会一直等待GPU发出接到命令的回复,如果柱状图很高,就意味着GPU太繁忙了。

紫色段表示将资源转移到渲染线程的时间,只有Android 4.0及以上版本才会提供。

在实际开发中,从图上虽然可以看到绘制的时间,但对不便于进行数据分析,比如进入某一个页面,柱形图虽然实时绘制出来,但不能更好地分析,这里可以通过:adb shell dumpsys gfxinfo com.**.**(包名)把具体的耗时输出到日志中来分析。

任何时候超过绿线(警戒线,对应时长16ms),就有可能丢失一帧的内容,虽然对于大部分应用来说,丢失几帧确实感觉不出卡顿,但保持UI流畅的关键就在于让这些垂直的柱状条尽可能地保持在绿线下面。

GPU Prof?ile工具能够很好地帮助你找到渲染相关的问题,但是要修复这些问题就不是那么简单了。需要结合另一个耗时工具和代码来具体分析,找到性能的瓶颈,并进行优化。在GPU Prof?ile Render发现有问题的页面后,可以通过另外一个工具Hierarchy Viewer来查看页面的布局层次和每个View所花的时间,在后面的布局优化章节,将通过实例来讲解和学习使用方法。

2.2.2 TraceView

TraceView是AndroidSDK自带的工具,用来分析函数调用过程,可以对Android的应用程序以及Framework层的代码进行性能分析。它是一个图形化的工具,最终会产生一个图表,用于对性能分析进行说明,可以分析到应用具体每一个方法的执行时间,使用可以非常直观简单,分析性能问题很方便。

1.?使用方法

在使用TraceVeiw分析问题之前需要得到一个*.trace的文件,然后通过TraceView来分析trace文件的信息,trace文件的获取有两种方式:

(1)在DDMS中使用

1)连接设备。

2)打开应用。

3)打开DDMS(若在Android Studio中则先打开Android Device Monitor)。

4)单击Strart Method Prof?iling按钮,如图2-14所示。

 

图2-14 在DDMS中打开TraceView

5)在应用中操作需要监控的点,比如进入一个Activity或者滑动一个列表,完成后单击Stop Method Prof?iling按钮,如图2-15所示。

 

图2-15 结束一次TraceView

6)结束会自动跳转到TraceView视图。

这种方法使用方便,但监控范围不够精确,如果需要精确监控某一个路径,就需要使用下一个方法:在代码中加入调试语句保存Trace文件。

(2)代码中加入调试语句保存trace文件

有时在开发过程中不好复现的问题,需要在关键的路径上获取TraceView数据,在测试时复现此问题后直接拿到Trace文件查看对应的数据。这时可以在代码中使用TraceView工具并生成对应的trace文件。在android.os.Debug类中提供了相应的方法,过程很简单步骤如下:

1)在需要开始监控的地方调用startMethodTracing()。

2)在需要结束监控的地方调用stopMethodTracing()。

3)系统会在SD卡中创建<trace-name>.trace文件。

4)使用traceveiw打开该文件进行分析。

调用代码如下:

// start tracing to "/sdcard/ui_performance.trace"

Debug.startMethodTracing("ui_performance");

// ...

// stop tracing

Debug.stopMethodTracing();

在应用程序中调用startMethodTracing()时,系统会在指定的路径上创建一个名为<trace_f?ilename>.trace文件。这个文件包含了方法名跟踪数据,以及与线程和方法名的映射表。然后系统开始缓存应用产生的跟踪数据,直到应用程序调用stopMethodTracing()结束,此时将其缓冲的数据写入输出文件中。如果系统达到最大缓存大小时,还没有调用stopMethodTracing(),系统会停止跟踪并发送一个通知。

在Android 4.4及更高版本中,可以通过基于采样的方法分析耗时情况,因为减少了分析Trace文件的次数,降低了IO读写,所以可以减少Trace工具在运行时对性能的影响,同时对分析结果也不会有很大的偏差。通过调用startMethodTracing()方法,就可以指定具体的采样间隔,定期采集样本数据分析。

在代码中使用此方法保存TraceView数据,不要忘记在应用中打开write to external storage权限(WRITE_EXTERNAL_STORAGE)。

2.?TraceView视图说明

Traceview视图分两部分,上半部分为时间片面板(Timeline Panel),下半部分为分析面板(Prof?ile Panel)。

时间片面板如图2-16所示。

 

图2-16 时间片面板

X轴表示时间消耗,单位为毫秒(ms),Y轴表示各个线程,每个线程中的不同方法使用了不同的颜色来表示,颜色占用面积越宽,表示该方法占用CPU时间越长。

时间片面板可以放大/缩小,也可以指定区域放到最大,方便查看具体的过程,一般优先选择放大耗时严重的区域。

分析面板(Prof?ile Panel)如图2-17所示。

 

图2-17 分析面板

分析面板看起来并不复杂,但需要理解各列数据的意义,每一列表示的意义如表2-1所示。

表2-1 分析面板参数意义

列  名 意  义

Name 所有的调用项,展开可以看到有的有Parent和Children子项,指被调用和调用

Inclusive 统计函数本身运行的时间+调用子函数运行的时间

incl inclusive时间占总时间的白分比

Exclusive 同级函数本身运行的时间

Excl 执行占总时间的白分比

Calls + Recur Calls / Total 该方法调用次数+递归次数

Cpu Time / Call 该方法耗时

Real Time / Call 实际时长

 

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

耗时。

RealTime与cputime区别为:因为RealTime包括了CPU的上下文切换、阻塞、GC等,所以RealTime方法的实际执行时间要比CPU Time稍微长一点。

2.2.3 Systrace UI性能分析

在应用程序开发过程中,UI(用户界面)的流畅度是体验的核心,特别是在动画、跳转或者列表的滑动过程中,出现卡顿和无响应是非常影响用户体验的,要解决这些问题,首先要找到问题的原因,前面介绍的TraceView是分析性能的一款利器,下面再介绍一个分析应用程序UI性能的工具:Systrace。

Systrace是Android 4.1及以上版本提供的性能数据采样和分析工具。它可以帮助开发者收集Android关键子系统(如surfacef?linger、WindowManagerService等Framework部分关键模块、服务,View系统等)的运行信息,从而帮助开发者更直观地分析系统瓶颈,改进性能。Systrace的功能包括跟踪系统的I/O操作、内核工作队列、CPU负载等,在UI显示性能分析上提供很好的数据,特别是在动画播放不流畅、渲染卡等问题上。Systrace工具可以跟踪、收集、检查定时信息,可以很直观地查看CPU周期消耗的具体时间,显示每个线程和进程的跟踪信息,使用不同颜色来突出问题的严重性,并提供如何解决这些问题的建议。

由于Systrace是以系统的角度返回一些信息,并不能定位到具体耗时的方法,要进一步获取CPU满负荷运行的原因,就需要使用前面介绍过的工具Traceview。

1.?Systrace使用方法

Systrace的使用不复杂。但跟踪的设备必须是Android 4.1(API16)或更高版本。在4.3版本和4.3以前版本的使用上有些区别,后面会讲到。

4.3以前系统版本的设备需要打开Settings > Developer options > Monitoring > Enable traces。

(1)在DDMS上使用

在Eclipse和Android Studio中都可以在DDMS直接使用Systrace,其他IDE也能支持,且流程都相同,下面以Android Studio为例说明其使用流程。

1)打开Android Device Monitor,连接手机并准备需要抓取的界面。

2)单击Systrace按钮进入抓取前的设置,选择需要跟踪的内容(见图2-18):

3)手机上开始操作需要跟踪的过程(如滑动列表)。

4)到了设定好的时间后,生成Trace文件。

5)使用Chrome打开文件即可分析。

(2)使用命令行

使用命令行方式更灵活,速度更快,并且配置好后再使用能快速得到结果,在Android 4.3及更高版本的设备上使用Systrace时,可以省略设置跟踪类别标签来获取默认值,或者可以手动列入指定标签。命令如下:

$ cd android-sdk/platform-tools/systrace

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

其中参数设置对应的功能如表2-2所示。

表2-2 System参数命令

参数名 意  义

-h, --help 帮助信息

-o <FILE> 保存的文件名

-t N, --time=N 多少秒内的数据,默认为5秒,以当前时间点往后倒N秒时间

-b N, --buf-size=N 单位为千字节,限制数据大小

-k <KFUNCS> --ktrace=<KFUNCS> 追踪特殊的方法

-l, --list-categories 设置需要追踪的标签

-a <APP_NAME>, --app=<APP_NAME> 包名

--from-f?ile=<FROM_FILE> 创建报告的来源trace文件

-e <DEVICE_SERIAL>, --serial=<DEVICE_SERIAL> 设备号

 

其中categories中的标签比较多,可以从官方的文档上查询:http://developer.android.com/intl/zh-cn/tools/help/systrace.html

(3)应用中获取

Systrace不会追踪应用的所有工作,所以在有需求的情况下,需要添加要追踪的代码部分。在Android 4.3及以上版本的代码中,可以通过Trace类来实现这个功能。它能够让你在任何时候跟踪应用的一举一动。在获取Trace的过程中,即Trace.beginSection()与Trace.endSection()之间的代码工作会一直被追踪。

在代码中加入Trace跟踪需要注意以下两点:

在Trace被嵌套在另一个Trace中时,endSection()方法只会结束离它最近的一个beginSection(String),即在一个Trace的过程中是无法中断其他Trace的。所以要保证endSection()与beginSection(String)调用次数匹配。

Trace的begin与end必须在同一线程中执行。

下面这部分代码为使用Trace的例子,在整个方法中含有两个Trace块,可以根据需求定义更多的块,但都要成对出现,如果有开始块但没有结束块,会严重影响应用的性能。

public void ProcessPeople() {

    Trace.beginSection("ProcessPeople");

    try {

        Trace.beginSection("Processing Jane");

        try {

            // code for Jane task...

        } finally {

            Trace.endSection(); // ends "Processing Jane"

        }

        Trace.beginSection("Processing John");

        try {

            // code for John task...

        } finally {

            Trace.endSection(); // ends "Processing John"

        }

    } finally {

        Trace.endSection(); // ends "ProcessPeople"

    }

}

2.?分析Systrace报告

通过前面方法获取到的trace.html文件,需要使用Chrome打开,有一些常用的快捷键,定义如表2-3所示。

目前Systrace产生的trace文件只能使用Chrome打开,使用Chrome打开文件后如图2-19所示。

从图2-19中可以看到完整的数据,其中和UI绘制关系最密切的是Alerts和Frame两个数据,接下来重点介绍Alerts和Frame。

 

图2-19 Systrace Viewer

(1)Alerts

从图2-19可以看到,Alerts一栏标记了性能有问题的点,单击该点可以查看详细信息,在右边侧边栏还有一个Alerts框,单击可以查看每个类型的Alerts的数量,单击某一个Alert可以看到问题的详细描述。

(2)Frame

每个应用都有一行专门显示frame,每一帧就显示为一个绿色的圆圈。当显示为黄色或者红色时,它的渲染时间超过了16.6ms(即达不到60fps的水准)。使用W键放大,看看这一帧的渲染过程中系统到底做了什么,同时它会将任何它认为性能有问题的东西都高亮警告,并提示要怎么优化。如图2-19所示,在Frame栏有一个F帧(第二帧)黄色告警,从下面的问题详细描述可以看出,警告的主要原因是ListView的回收和重新绑定花费太多时间。在Systrace中也会提供一些对应链接,提供更多解释。

如果想知道UI线程怎么会花费这么多时间的话,就需要使用2.2.2节讲到的TraceView,来分析具体是哪些函数在消耗时间。

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
16天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
17天前
|
缓存 监控 Android开发
安卓应用性能优化的实用策略
【4月更文挑战第2天】 在竞争激烈的应用市场中,一款应用的性能直接影响用户体验和市场表现。本文针对安卓平台,深入探讨了性能优化的关键要素,包括内存管理、代码效率、UI渲染和电池使用效率。通过分析常见的性能瓶颈,并提供针对性的解决策略,旨在帮助开发者构建更加流畅、高效的安卓应用。
|
17天前
|
数据库 Android开发 开发者
构建高效Android应用:Kotlin协程的实践指南
【4月更文挑战第2天】随着移动应用开发的不断进步,开发者们寻求更流畅、高效的用户体验。在Android平台上,Kotlin语言凭借其简洁性和功能性赢得了开发社区的广泛支持。特别是Kotlin协程,作为一种轻量级的并发处理方案,使得异步编程变得更加简单和直观。本文将深入探讨Kotlin协程的核心概念、使用场景以及如何将其应用于Android开发中,以提高应用性能和响应能力。通过实际案例分析,我们将展示协程如何简化复杂任务,优化资源管理,并为最终用户提供更加流畅的体验。
|
18天前
|
开发框架 安全 Android开发
探索安卓系统的新趋势:智能家居应用的蓬勃发展
随着智能家居概念的兴起,安卓系统在智能家居应用领域的应用日益广泛。本文将探讨安卓系统在智能家居应用开发方面的最新趋势和创新,以及其对用户生活的影响。
13 2
|
21天前
|
缓存 监控 Java
构建高效Android应用:从优化用户体验到提升性能
在竞争激烈的移动应用市场中,为用户提供流畅和高效的体验是至关重要的。本文深入探讨了如何通过多种技术手段来优化Android应用的性能,包括UI响应性、内存管理和多线程处理。同时,我们还将讨论如何利用最新的Android框架和工具来诊断和解决性能瓶颈。通过实例分析和最佳实践,读者将能够理解并实施必要的优化策略,以确保他们的应用在保持响应迅速的同时,还能够有效地利用系统资源。
|
21天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
18天前
|
Java Android开发 开发者
构建高效Android应用:Kotlin协程的实践与优化
在响应式编程范式日益盛行的今天,Kotlin协程作为一种轻量级的线程管理解决方案,为Android开发带来了性能和效率的双重提升。本文旨在探讨Kotlin协程的核心概念、实践方法及其在Android应用中的优化策略,帮助开发者构建更加流畅和高效的应用程序。通过深入分析协程的原理与应用场景,结合实际案例,本文将指导读者如何优雅地解决异步任务处理,避免阻塞UI线程,从而优化用户体验。
|
2天前
|
缓存 移动开发 Android开发
构建高效Android应用:从优化用户体验到提升性能表现
【4月更文挑战第18天】 在移动开发的世界中,打造一个既快速又流畅的Android应用并非易事。本文深入探讨了如何通过一系列创新的技术策略来提升应用性能和用户体验。我们将从用户界面(UI)设计的简约性原则出发,探索响应式布局和Material Design的实践,再深入剖析后台任务处理、内存管理和电池寿命优化的技巧。此外,文中还将讨论最新的Android Jetpack组件如何帮助开发者更高效地构建高质量的应用。此内容不仅适合经验丰富的开发者深化理解,也适合初学者构建起对Android高效开发的基础认识。
2 0
|
2天前
|
移动开发 Android开发 开发者
构建高效Android应用:采用Kotlin进行内存优化的策略
【4月更文挑战第18天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,由于设备和版本的多样性,确保应用流畅运行且占用资源少是一大挑战。本文将探讨使用Kotlin语言开发Android应用时,如何通过内存优化来提升应用性能。我们将从减少不必要的对象创建、合理使用数据结构、避免内存泄漏等方面入手,提供实用的代码示例和最佳实践,帮助开发者构建更加高效的Android应用。
5 0
|
3天前
|
缓存 移动开发 Java
构建高效的Android应用:内存优化策略
【4月更文挑战第16天】 在移动开发领域,尤其是针对资源有限的Android设备,内存优化是提升应用性能和用户体验的关键因素。本文将深入探讨Android应用的内存管理机制,分析常见的内存泄漏问题,并提出一系列实用的内存优化技巧。通过这些策略的实施,开发者可以显著减少应用的内存占用,避免不必要的后台服务,以及提高垃圾回收效率,从而延长设备的电池寿命并确保应用的流畅运行。

推荐镜像

更多