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