Android Systrace

为什么使用systrace

  • 能够捕获一段时间内Android系统的运行状态,生成html图
  • 分析Android系统/应用的显示、绘制等性能问题

如何抓取systrace

  1. Android Studio(Tools->Android->Android Device Monitor)
  2. 使用sdk/platform-tools/systrace中的systrace.py
  3. adb shell下使用atrace
  4. 直接使用Ftrace

在代码中添加trace

Java代码中添加

  • 使用beginSection API

注意,使用此方法只有在应用的debuggable为true,并且在抓取systrace的时候选定该进程才有效。

Trace.beginSection("traceName");
registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
Trace.endSection();
  • 反射使用traceBegin API
public class TraceUtil {
    private static final String LOG_TAG = TraceUtil.class.getSimpleName();
    private static final String TRACE_MARKER_PATH = "/sys/kernel/debug/tracing/trace_marker";
    // Using VIEW option, also using others, but APP
    private static final long TRACE_TAG_VIEW = 1L << 3;

    public static void begin(String methodName) {
        Log.i(LOG_TAG, "Trace being...");

        try {
            Method traceBegin = Trace.class.getDeclaredMethod("traceBegin", long.class, String.class);
            traceBegin.invoke(Trace.class, TRACE_TAG_VIEW, methodName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void end() {
        Log.i(LOG_TAG, "Trace end...");

        try {
            Method traceEnd = Trace.class.getDeclaredMethod("traceEnd", long.class);
            traceEnd.invoke(Trace.class, TRACE_TAG_VIEW);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void traceMarkerBegin(String methodName) {
        Log.i(LOG_TAG, "traceMarkerBegin");

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(new File(TRACE_MARKER_PATH));

            try {
                fileOutputStream.write(("B|" + Process.myPid() + "|" + "wlb").getBytes());
                fileOutputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // No Need Close
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void traceMarkerEnd() {
        Log.i(LOG_TAG, "traceMarkerEnd");

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(new File(TRACE_MARKER_PATH));

            try {
                fileOutputStream.write(("E").getBytes());
                fileOutputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // No Need Close
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
TraceUtil.begin("wlb");
registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
TraceUtil.end();
  • 直接写trace_marker
TraceUtil.traceMarkerBegin("traceName");
registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
TraceUtil.traceMarkerEnd();

Native代码中添加

  • 使用NDK提供的API
typedef void (*func_p)(void);

static void trace_func(void)
{
    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Test Native Trace");
}

static void test_native_trace(func_p)
{
    if (ATrace_isEnabled()) {
        ATrace_beginSection("traceName");
        func_p();
        ATrace_endSection();
    }
}
  • 直接写trace_marker
static inline void begin_trace(int fd)
{
    char buf[MAX_BUFF_SIZE];
    int len = snprintf(buf, MAX_BUFF_SIZE, "B|%d|%s", getpid(), "traceName");

    if (fd > 0)
        write(fd, buf, len);
}

static inline void end_trace(int fd)
{
    if (fd > 0)
        write(fd, "E", 1);
}

// Note: Not close trace_marker fd
static void test_trace_marker(func_p)
{
    const char *trace_marker_path = "/sys/kernel/debug/tracing/trace_marker";
    int tm_fd = open(trace_marker_path, O_WRONLY);

    if (tm_fd < 0) {
        return;
    }

    begin_trace(tm_fd);
    func_p();
    end_trace(tm_fd);
}
Android Systrace_第1张图片

systrace的工作原理

Android Systrace_第2张图片

使能systrace workflow

Android Systrace_第3张图片
j3y17qltecmcc:/sys/kernel/debug/tracing # ls
README                          kprobe_events       trace
available_events                kprobe_profile      trace_clock
available_tracers               options             trace_marker
buffer_size_kb                  per_cpu             trace_options
buffer_total_size_kb            printk_formats      trace_pipe
cpu_freq_switch_profile_enabled saved_cmdlines      tracing_cpumask
current_tracer                  saved_cmdlines_size tracing_max_latency
events                          saved_tgids         tracing_on
free_buffer                     set_event           tracing_thresh
instances                       snapshot
  • trace
  • trace_marker
  • buffer_size_kb
  • tracing_on

细节参考/android/kernel/Documentation/trace/下Ftrace文档

应用systrace workflow

Android Systrace_第4张图片

你可能感兴趣的:(Android Systrace)