您的位置:

Systrace.py的多方位分析

一、Systrace.py是什么?

Systrace是一款由Android操作系统提供的工具,它有助于在Android设备中级别的Tracing,同时它也是一种用于记录所有进程(CPU、内存、GPU等)的完整分析工具。Systrace.py则是Systrace提供的Python API,帮助开发人员对Systrace命令进行更具有扩展性的编程和限制。(默认情况下,Systrace只对Google代码和系统支持的设备提供支持,在UI层捕获trace信息,并且输出一个HTML report文件,但是Systrace.py则可以实现类似的效果,其排放密度甚至更强)。

二、Systrace.py的特点

除了与官方Systrace命令具有相同的特点外,Systrace.py还添加了一些值得注意的特性,例如:

  • 可以为您提供更好的控制权,分别捕获跨多个进程和线程的轨迹数据。
  • 可以利用Systrace功能分析的优点,帮助查明繁忙代码段的性能瓶颈。
  • 可以对大量不同类型的事件进行过滤与调试。
  • 支持各种标记,并且提供了丰富的过滤器。
  • 可以集成到Jenkins的构建中以及与其他分析工具一起使用。

三、Systrace.py的用途

Systrace是针对应用程序和系统性能的一种分析工具,那么在实际的开发过程中,Systrace.py可以有哪些用途呢?

  1. 追踪应用程序性能问题分析(例如卡顿、掉帧、耗电量、启动时间等)。
  2. 支持在自动化测试中检测应用程序性能和其它是否满足要求(例如,会导致内存泄漏的问题或者处理器运行时间是否在预期范围内)。
  3. 为发现系统优化带来便利(例如,对输入事件分析以确定问题的根本原因)。

四、Systrace.py的示例代码

#继承SystraceBuilder类,获取所需或将在命令中呈现的数据。
class MySpecificTracing(SystraceBuilder):
    def __init__(self, bufferSize):
          super().__init__(duration, app, bufferSize)
    #重载设置方法,用于定义已包含在命令中的特定项。
    def set_categories(self):
         self.add_categories('audio', 'bionic', 'view', 'wm', 'audio-hal', 'audio-policy', 'scsi', 'dalvikvm', etc.)
 
 #将一个特制跟踪类的对象传递给systrace的popen函数
 with MySpecificTracing(4096) as p:
   p.run()

五、Systrace.py的过滤器

Systrace.py的主要目的之一是能够在Systrace命令中指定过滤器,以下面的例子为例。

#创建一个过滤器对象
filter = FiltersBuilder()
 
#将组件添加到过滤器中
filter.add_categories("wm", "sched", "freq", "idle")
 
#添加一个条件触发器(就像“when”补丁)
filter.set_trigger(title="Power connected", predicate='arg.name=="ac" and arg.value=="1"')
 
#添加一个即时操作(通过在TextProgressBar上设置动画效果)
filter.add_action(title="Downloading", duration=5, widget=TextProgressBar())
 
#将过滤器连接到我们的跟踪器上
with TraceStreamerBuilder(flush_time=10, block=True, shell=True) as t:
    t.add_filter(filter)
 
    #注册所需事件列表。
    t.set_events("sched", "freq", "idle", "wm")
 
    #解决要跟踪的特定PID(也可以使用all_thread/tag/pid函数)
    pid = find_pid_from_package('com.acme.app')
 
    #启动刘易斯P:D(命令行调试)以获取跟踪数据。
    t.start(subprocess_flags=["-p", pid])

六、Systrace.py的可读性

Systrace.py不仅具有优秀的功能性,还比Systrace命令产生的简单文本结果更易于理解和使用。我们知道,Systrace命令默认会在$ANDROID_HOME/platform-tools/systrace/下生成一个HTML文件。而在经过Systrace.py的处理后,其生成的结果具有更好的易读性。

#创建一个过滤器对象
filter = FiltersBuilder()
 
#将组件添加到过滤器中
filter.add_categories('drivers', 'binder_driver', 'workqueue', 'atomic', 'sync')
 
#将过滤器连接到我们的跟踪器上
with TraceStreamerBuilder(flush_time=10, block=True, shell=True) as t:
    t.add_filter(filter)
 
    #注册所需事件列表。
    t.set_events('binder', 'workqueue', 'futex', 'drivers', 'irq')
 
    #将跟踪器与指定PID连接(也可以使用all_thread/tag/pid函数)。
    pid = find_pid_from_package('com.acme.app')
 
    #启动刘易斯P:D(命令行调试)以获取跟踪数据。
    t.start(subprocess_flags=['-p', pid])
    
    # 将跟踪数据文件写入压缩文件
    with open("my_trace.bytes", 'wb') as f:
        f.write(t.buf.getvalue())
    
    # 使用systrace.py库中的方法生成分析报告
    trace = Trace(my_trace.bytes, MultiFileProvider('*.chr'), True, True)
    report = Report(trace)
    report.build()
    
    # 存储生成的分析报告文件
    with open("my_trace.html", 'w') as f:
        f.write(report.report_html)