原生跟踪

本指南介绍如何使用原生跟踪 API (trace.h),将跟踪事件写入系统缓冲区。 然后,您可通过使用 Systrace 工具,分析此跟踪输出。 Android API 级别 23 及更高版本支持原生跟踪 API。

概览

如所述,在原生代码中创建自定义跟踪与 Java 编程语言的技巧相似跟踪应用代码。 一般来说,您不必将原生跟踪代码输入 try/catch 块,除非跟踪的分区引发原生异常,或使用早期返回。

除非可能造成跟踪文件损坏,否则请针对每个 ATrace_beginSection() 调用,执行相应的 ATrace_endSection() 调用。

若要在未启用跟踪时避免构建复杂字符串或参数,您可通过调用 ATrace_isEnabled() 添加锁定

跟踪功能

原生跟踪 API 的一个用例是观察特定代码块使用的时间。 一般来说,此类跟踪发生在管道处理阶段(例如,解码图像、绘制帧或等待网络请求时)。

若要跟踪代码块使用的时间,请遵循以下步骤:

  1. 添加 trace.h 标头文件。
    #include <android/trace.h>
    
  2. 指定一个变量作为以下项目的分区名称: ATrace_beginSection()。 在要跟踪的代码块末尾,针对以下项目执行相应的调用: ATrace_endSection()。 当跟踪的分区引发原生异常或使用早期返回时,这一点尤其重要。
    void myExpensiveFunction() {
      ATrace_beginSection("myExpensiveFunction");
      ... // trace-worthy work here
      ATrace_endSection();
    }
    
  3. (可选)创建便捷的对象/宏结构来跟踪代码块。 以下示例显示您如何实现此类名为 ATRACE_CALL() 的对象/宏。
    #define ATRACE_NAME(name) ScopedTrace ___tracer(name)
    
    // ATRACE_CALL is an ATRACE_NAME that uses the current function name.
    #define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
    
    class ScopedTrace {
      public:
        inline ScopedTrace(const char *name) {
          ATrace_beginSection(name);
        }
    
        inline ~ScopedTrace() {
          ATrace_endSection();
        }
    };
    
    您可使用 ATRACE_CALL() 对象/宏,按照如下方式简化上一步中的代码。 通过这种方式使用对象/宏,当跟踪的分区引发异常或使用早期返回时,您无需担心添加 try/catch 块。
    void myExpensiveFunction() {
      ATRACE_CALL();
      ... // trace-worthy work here
    }