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):

图2-18 DDMS上打开Systrace

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参数命令

其中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所示。

表2-3 Systrace快捷键

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

图2-19 Systrace Viewer

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

(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,来分析具体是哪些函数在消耗时间。