使用Systrace分析UI性能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cxq234843654/article/details/74206098

使用Systrace分析UI性能

原文地址:https://developer.android.com/studio/profile/systrace.html

在开发应用时,通常使用60fps的帧率来检测交互是否流畅,如果中途出错了,或者发生了掉帧,解决这个问题的第一步应当是搞清楚当前系统在做什么。

Systrace工具可以在程序运行的时候收集实时的信息,记录时间以及CPU的分配情况,记录每个线程和进程在任意时间的运行情况,可以自动分析出一些重要的原因,并且给出建议。

预览

Systrace可以帮助你分析应用是如何设备上运行起来的,它将系统和应用程序线程集中在一个共同的时间轴上,分析systrace的第一步需要在程序运行的时间段中抓取trace log,在抓取到的trace文件中,包含了这段时间中你想要的关键信息,交互情况。

图1

图1显示的是当一个app在滑动时出现了卡顿的现象,默认的界面下,横轴是时间,纵向为trace event,trace event 先按进程分组,然后再按线程分组.

从上到下的信息分别为Kernel,SurfaceFlinger,应用包名。通过配置trace的分类,可以根据配置情况记录每个应用程序的所有线程信息以及trace event的层次结构信息。

生成trace

首先需要一些准备工作:
第一,android 4.1及以上的设备
第二,开启调试模式,安装你的应用
第三,某些trace信息需要root权限才能够获取,比如 disk activity和工作队列等,但是大部分都不需要root权限。

systrace的追踪有两种方式:一种是通过命令行(待补充),一种是通过图形界面(待补充)。

android4.3及以上

通过以下命令获取:

$ cd android-sdk/platform-tools/systrace
$ python systrace.py --time=10 -o mynewtrace.html sched gfx view wm

android4.2及以下

在低于android4.2的设备上,需要事先做一些配置,当你需要收集如下信息是:
- 收集graphics,aduio以及输入进程信息(通过配置–set-tags= 获取)
- 收集CPU,disk,kernel以及dish activity信息(通过配置option来获取)

通过命令行来配置tages

  1. 使用 –set-tags选项:
$ cd android-sdk/platform-tools/systrace
$ python systrace.py --set-tags=gfx,view,wm
  1. 关闭、重启adb
$ adb shell stop
$ adb shell start

通过图形界面

  1. 在android设备的 设置 – 开发者选项 – 监控 – 开启traces
  2. 选择要追中的类别,并且点击确定

注意:无需重启adb服务

完成以上配置后,开始抓trace文件

$ python systrace.py --cpu-freq --cpu-load --time=10 -o mytracefile.html

分析trace文件

抓到trace.html文件后,通过web浏览器打开

检查Frames

每个应用程序都有一排代表渲染帧的圆圈,通常为绿色,如果绘制的时间超过16.6毫秒则显示黄色或红色。通过“W”键查看帧。

注意:输入“?”可以查看帮助

图2:帧未被选中

点击帧,则下方将显示系统为该帧所做的工作。在运行Android 5的设备(API Level 21)或更高,这项工作分为UI线程和render线程。而在以前的版本中,创建帧的所有工作都是在UI线程上完成的。
点击帧的各个组件,可以查看它们的运行时间,事件(如performtraversals),当你选择某个方法时,也会显示该方法的执行过程。点击最下方的alert,将显示alert的具体信息。

Alerts的审查

Systrace会自动分析trace event,在alerts中指出性能问题,并且给出相应的建议。

图3:选中某一帧

选择慢帧(如图3的黄色圆圈所示)之后,将在底部显示一个警报。在Description一栏中,将看到变慢的原因(ListView在回收和重绘的时候,由于超负荷的工作导致慢帧),trace中有相关事件的链接,可以进一步解释系统在这段时间内正在做什么。

如果许多ListView工作都在UI线程中进行的,那么你可以使用Traceview(https://developer.android.com/studio/profile/traceview.html)代码性能能分析工具,分析具体是在哪一些方法耗时过多。然后,在这些方法上添加trace marker(可参见下一节的见trace应用程序代码)的功能获得更具体的定位。

注意,您还可以通过单击窗口右侧边的Alert选项卡来查找trace中的每个警报,在弹出的侧边框中那里您可以看到trace中警告以及事件计数。

图4:点击右侧边栏的alert获取更多alert信息

Alert面板会将trace中的问题呈现出来,以及这些问题造成卡顿的频率,

帮助你看到问题发生的痕迹,以及如何他们往往有助于该。Alert面板可以看成一个是待修复的bug列表,通常一个区域的微小变化或改进可以消除应用程序中的所有类警报!

trace应用程序代码

在framework中的trace marker并没有覆盖到你的所有代码,因此有些时候你需要自己去定义trace marker。在Android4.3之后,可以通过Trace类在代码中添加标记,这样你将能够看到在指定时间内应用的线程在做哪些工作,当然,trace 的begin和end操作也会增加一些额外的开销,但都只有几微秒左右。

通过下面的例子来说明Trace类的 用法。

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {

    ...

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Trace.beginSection("MyAdapter.onCreateViewHolder");
        MyViewHolder myViewHolder;
        try {
            myViewHolder = MyViewHolder.newInstance(parent);
        } finally {
            Trace.endSection();
        }
        return myViewHolder;
    }

   @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Trace.beginSection("MyAdapter.onBindViewHolder");
        try {
            try {
                Trace.beginSection("MyAdapter.queryDatabase");
                RowItem rowItem = queryDatabase(position);
                mDataset.add(rowItem);
            } finally {
                Trace.endSection();
            }
            holder.bind(mDataset.get(position));
        } finally {
            Trace.endSection();
        }
    }

…

}

注意:endSection和beginSection遵循就近匹配原则,因此注意控制他们的匹配顺序。

注意:begin和end必须在同一个线程中。

注意:如果begin被try catch语句包含了,则endSestion必须放到finally语句块中。

使用应用程序级跟踪Systrace时,您必须指定应用程序包名。
在分析应用程序时,你应该启用应用程序级跟踪,即使你没有在你的应用程序中添加你自己的跟踪标记。只有当你开启了应用级别的trace,许多lib库,如recyclerview,包括trace marker才能提供有用的信息。

猜你喜欢

转载自blog.csdn.net/cxq234843654/article/details/74206098