Android性能优化工具

article/2025/10/14 19:09:55

一、性能优化工具基础

1.1 概述

  在Android开发中,开发者可通过"系统跟踪"观察Android设备的运行情况并生成跟踪报告,在此基础上进行分析优化。Android 平台提供了多种获取跟踪信息的工具:

  • Android Studio CPU 性能剖析器
  • Systrace 命令行工具
  • Perfetto 命令行工具
  • "系统跟踪"应用

  其中,Android Studio CPU Profiler性能剖析器可实时检查应用的 CPU 使用率和线程活动,此外还可以查看方法跟踪记录、函数跟踪记录和系统跟踪记录中的详细信息。与CPU Profiler功能类似的TraceView、DDMS已弃用。

  Systrace 是Android SDK Tools提供的旧版命令行工具,可记录短时间内的设备活动,并保存在压缩的文本文件中。该工具会生成一份html报告,其中汇总了 Android 内核中的数据,例如 CPU 调度程序、磁盘活动和应用线程。

  Perfetto 是 Android 10 中引入的全新平台级跟踪工具,与Systrace类似,同样会生成汇总了Android 内核数据(例如CPU 调度程序、磁盘活动和应用线程)的跟踪文件。与 Systrace 不同的是,跟踪文件会以 Perfetto 格式保存,它提供数据源超集,可让您以 protobuf 编码的二进制流形式记录任意长度的跟踪记录。

  "系统跟踪"应用是一款用于将设备活动保存到跟踪文件的 Android 工具。在搭载 Android 10(API 级别 29)或更高版本的设备上,跟踪文件会以 Perfetto 格式保存。在搭载较低版本 Android 系统的设备上,跟踪文件会以 Systrace 格式保存。

1.2 例子

  下面通过一个例子介绍如何用上面几种工具进行分析,例如在OpenCVActivity中点击"BC OPENCV BEFORE"按钮时,执行《Android OpenCV基础(三、图片处理)》中比较耗时的高斯滤波,代码如下:

public class OpenCVActivity  extends Activity implements View.OnClickListener {private ImageView imageView1;private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.open_cv_activity_layout);imageView1 = findViewById(R.id.opencv_sample_image_view);button = findViewById(R.id.opencv_sample_button);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.opencv_sample_button) {Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.adventure_time);// 高斯滤波Bitmap bitmap1 = OpenCVSample.blurBitmap(bitmap, 30);imageView1.setImageBitmap(bitmap1);Toast.makeText(this, "ok", Toast.LENGTH_SHORT).show();button.setText("BC OpenCV After");}}
}

  点击按钮后的执行效果如下图所示,后面几个小节介绍如何通过性能分析工具分析点击按钮后的方法执行情况。
image.png

二、性能剖析器

  Android Studio性能剖析器是Android Studio提供的一个可视化分析工具,可实时显示应用的 CPU、内存、网络和电池资源使用情况。Android Studio 3.0 及更高版本中的 Android Profiler 取代了 Android Monitor 工具。如下图所示,性能剖析器展示了四类信息:CPU、MEMORY、NETEORK、ENERGY,点击后可分别进入CPU性能分析,内存性能分析、网络性能分析、电池性能分析:
image.png
  其中在点击CPU时间轴后,进入的CPU Profiler常用来分析方法执行耗时情况。

2.1 CPU Profiler介绍

  CPU 性能分析器可以在APP运行时,实时检查应用的 CPU 使用率和线程活动,也可以检查记录的方法轨迹、函数轨迹和系统轨迹的详情。

2.1.1 使用方法

  CPU Profiler使用方式为:

  1. 在 Android Studio 中,依次选择 View > Tool Windows > Profiler,或点击工具栏中的 Profile 图标。
  2. 在Android Studio Profiler中新建session,选择需要分析的设备及app进程。
  3. 点击 CPU 时间轴上的任意位置以打开 CPU 性能分析器。
  4. 从 CPU 性能分析器的配置菜单中选择 System Trace(详细配置介绍见2.2小节),然后点击 Record。完成与应用的交互后,点击 Stop Sample Java Method右边的"record"按钮后,CPU Profiler会对之后的方法执行进行采样,完成与应用的交互后,点击"stop"停止记录,并将这段时间的方法执行按顺序展示出来
    image.png
  5. 结束记录后,CPU 性能分析器会展示这段时间内的方法调用,开发者也可以点击保存把跟踪记录保存为.trace 文件。

2.1.2 使用举例

  在例子1.2中,我们点击页面中的"BC OPENCV BEFORE"按钮,在执行结束后停止记录,方法采样记录如下所示:
image.png
  在Android studio Profiler中,按"w"键可放大查看(按"s"可缩小、"a"左移、"d"右移、"0"复位),放大后如下图所示:
image.png
  可以看到,点击方法"performClick()"内先执行了"blurBitmap()"方法,然后执行了"imageView1.setImageBitmap()"方法,后面在主线程中继续执行了"doTraversal()"来更新view,方法执行顺序符合预期,同时可以看到"blurBitmap()"执行耗时较长,是需要进行优化的。接着,点击"blurBitmap"可以看到该方法的耗时总结,如下图所示:
image.png

  另外,CPU Profiler可以查看线程的运行情况,在这个例子中onClick()方法总耗时1350ms,其中Running状态占744ms(对应blurBitmap耗时),Idle状态占602ms(对应sleep耗时)。
image.png

2.1.3 查看方法跟踪

  下面介绍,如何查看CPU Profiler收集到的方法跟踪结果。结合例子2.1.2中收集到的方法跟踪结果可见,对系统 API 的调用显示为橙色,对应用自有方法的调用显示为绿色,对第三方 API(包括 Java 语言 API)的调用显示为蓝色。此外,CPU 性能分析器中的轨迹视图提供了多种方法查看所记录的轨迹的信息(例如Top Down、Flame Chart、Bottom Up、Event视图),开发者可自行切换视图查看,这里不再详细介绍。

  通常情况下,方法跟踪信息可以帮助您找出应用中用时最多的方法,帮助您定位并针对性分析优化。但是,方法跟踪不适合用于识别卡顿,因为它们会因开销过大而导致出现假正例卡顿,且无法查看线程何时运行以及何时处于阻塞状态。

2.2 CPU 记录配置

  2.1.1小节在步骤4中提到,Android Studio CPU Profiler提供了四种可选的记录配置,如下图所示,开发者可根据需要选择合适的配置。
image.png
  下面结合1.2中的例子,介绍四种配置的记录结果。

2.2.1 采样JAVA方法(Sample JAVA Methods)

  在CPU Profiler中选择"Sample JAVA Methods"后并点击"Record"按钮,CPU Profiler开始记录方法执行顺序,然后我们点击"1.2例子中APP上的blur按钮"完成需要分析的操作,接着点击CPU Profiler中的"Stop"按钮停止采集,最终得到如下记录结果:
image.png
  局部放大后如下图所示,可以看到部分耗时很短的方法未被采样,这是因为这种记录方式是间隔采样,再次采样时一些耗时很短的方法已经执行结束所以就没被记录下来。
image.png

2.2.2 跟踪JAVA方法(Trace JAVA Methods)

  同样地,在CPU Profiler中选择"Trace JAVA Methods",最终得到如下记录结果:
image.png
局部放大后,如下图所示,可以看到部分耗时很短的方法也被跟踪;
image.png

2.2.3 采样C/C++方法(Sample C/C++ Functions)

  同样地,在CPU Profiler中选择"Sample C/C++ Functions",最终得到如下记录结果,可以看到成功采集到了例子中"com_bc_sample_OpenCVSample_blurBitmap"的native方法调用:
image.png

2.2.4 跟踪系统调用(Trace System Calls)

  同样地,在CPU Profiler中选择"Trace System Calls",最终得到如下记录结果,可以看到SurfaceFlinger、VSYNC、RenderThread、app进程(com.bc.sample)的系统调用等信息:
image.png

2.3 CPU记录配置总结

  (1)Sample JAVA Methods不能采集耗时很短的方法,而Trace JAVA Methods可以采集耗时很短的方法;

  (2)Sample JAVA Methods和Trace JAVA Method会带来性能损耗,在DEMO中,Sample JAVA Methods和Trace JAVA Method记录到的方法执行耗时差别不大,但在大型APP中,Sample JAVA Methods收集到的方法执行耗时偏长,Trace JAVA Methods收集到的方法执行耗时比实际执行耗时更长,而且执行Trace JAVA Methods时APP卡顿比较明显;

  (3)Sample C/C++ Functions只能采集native层方法;

  (4)Trace System Calls可以采集SurfaceFlinger、VSYNC、RenderThread、app进程的系统调用等信息。

2.4 trace文件

  CPU 性能分析器可以把跟踪记录保存为.trace 文件。此外,开发者也可以自己保存trace文件,用CPU 性能分析器打开trace文件来查看函数调用。除了CPU 性能分析器外,以下几种方法也可以生成trace文件。

2.4.1 Debug API

  Android系统还提供了Debug类来跟踪方法执行顺序,并输出一个trace文件,开发者可使用Android Studio Profiler来查看trace文件。通过这种方式,开发者可以更精确地控制设备何时开始和停止记录跟踪信息。

  在执行Debug API开始跟踪后,方法执行速度会比实际执行速度慢很多,且默认情况下Debug的缓存空间限制是8MB(支持开发者配置更大的参数),因此DebugAPI专为时间间隔较短或难以手动启动/停止记录的场景而设计。

  Debug类通过startMethodTracing()和stopMethodTracing()结合使用,方法如下:

public void onClick(View v) {if (v.getId() == R.id.opencv_sample_button) {// 开始方法跟踪,默认参数为空,也可以传入指定路径// 默认输出路径是'/sdcard/Android/data/[application_pacake_name]/files/dmtrace.trace'Debug.startMethodTracing();Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.adventure_time);Bitmap bitmap1 = OpenCVSample.blurBitmap(bitmap, 30);imageView1.setImageBitmap(bitmap1);Thread.sleep(500);button.setText("BC OpenCV After");// 结束方法跟踪Debug.stopMethodTracing();}}

2.4.2 adb命令

  对于APP冷启动场景,还可以使用 adb am 命令记录方法跟踪,如下所示:

# 1.打开com.bc.example.MainActivity 并开始方法跟踪
# --sampling 100表示方法采样间隔
adb shell am start -n com.bc.example/com.bc.example.MainActivity --start-profiler /data/local/tmp/bc—sample.trace --sampling 100# 2.Activity启动后,输入以下命令停止跟踪
adb shell am profile stop <process># 3.把手机上的trace文件pull出来
adb pull /data/local/tmp/bc—sample.trace ./

2.4.3 simpleperf

  simpleperf也提供了冷启动方法跟踪的方法如下所示,暂不详细介绍。

# Start simpleperf recording, then start the Activity to profile.
$ ./app_profiler.py -p simpleperf.example.cpp -a .MainActivity# We can also start the Activity on the device manually.
# 1. Make sure the application isn't running or one of the recent apps.
# 2. Start simpleperf recording.
$ ./app_profiler.py -p simpleperf.example.cpp
# 3. Start the app manually on the device.

三、Systrace 命令行工具

  Systrace是一个Python脚本,是Android SDK tools提供的旧版本分析工具(在Android platform tools 33.0.1版本中已经移除systrace,建议用Studio 性能分析器、gpuinspector.dev 或 Perfetto 取代)。它记录了一段时间内的设备活动(包括CPU调度、磁盘操作、应用线程等信息),并产生一个HTML格式的Systrace报告,可以帮助开发者分析系统瓶颈,改进性能。

  systrace.py实际上是多种其他工具的封装容器:它是 atrace 的主机端封装容器。atrace 是用于控制用户空间跟踪和设置 ftrace 的设备端可执行文件,也是 Linux 内核中的主要跟踪机制。systrace 在主机端通过adb使用 atrace 来启用跟踪,然后读取 ftrace 缓冲区并生成易于查看的HTML。

3.1 使用方法

  Systrace 工具位于/Users/bc/Library/Android/sdk/platform-tools/systrace/systrace.py,使用方法如下:

# 使用方式为:python systrace.py [options] [categories]
# 其中,[options] 表示参数,可选的参数有:
#        -a 进程名
#        -b 跟踪缓冲区大小,单位KB
#        -o 输出文件名字
#        -t 跟踪设备活动 N,可不指定,用Enter键结束跟踪
# [categories]表示需要trace的类别,可选的跟踪信息有:
#       sched - CPU Scheduling;CPU 调度信息,例如线程调度、锁信息等;
#        load - CPU Load
#        view - View System;view绘制系统的相关信息,比如onMeasure,onLayout等,常用来分析卡顿
#        app - Application;应用的跟踪信息,如果设备不支持则不能收集APP的trace
#        gfx - Graphics;Graphic相关信息,包括SerfaceFlinger、VSYNC、Texture等,常用来分析卡顿
#       input - Input
#     webview - WebView
#          wm - Window Manager
#          am - Activity Manager
#          sm - Sync Manager
#       audio - Audio
#       video - Video
#      camera - Camera
#         hal - Hardware Modules
#         app - Application
#         res - Resource Loading
#      dalvik - Dalvik VM
#          rs - RenderScript
#      bionic - Bionic C Library
#       power - Power Management
#        freq - CPU Frequency
#        idle - CPU Idle
# 例如以下命令会生成名为my_systrace_report.html的跟踪文件
python /Users/bc/Library/Android/sdk/platform-tools/systrace/systrace.py -a com.bc.sample -b 16384 -o my_systrace_report.html app load view

  如下所示,在命令行运行Systrace后,可以按Enter键结束跟踪,结束后会将系统跟踪输出到html文件中。

➜ ~ python /Users/bc/Library/Android/sdk/platform-tools/systrace/systrace.py -a 
com.bc.example -b 16384 -o my_systrace_report.html app load view
These categories are unavailable: load
Starting tracing (stop with enter)
Tracing completed. Collecting output...
Outputting Systrace results...
Tracing complete, writing resultsWrote trace HTML file: file:///Users/bc/my_systrace_report.html

  打开结果html,可通过键盘WSAD放大缩小,左右移动来检查html,如下图所示:

image.png
  从上图可以看到,UI线程中只显示了系统方法调用情况,没有app中的方法调用,这是因为systrace默认只跟踪系统级别进程的信息,如果想跟踪自己APP相对系统事件的代码执行状态,需要在代码中增加自己的trace,即自定义事件(详见第5章节)。

3.2 查看Systrace报告

3.2.1 线程状态

  在3.2.3中生成html后,可通过键盘WSAD放大缩小,左右移动来检查html。点击UI thread、Render Thread等,可以看到线程的当前状态,如下所示:
image.png
  线程运行状态与颜色对应如下:

  • 绿色 : 运行中(Running)
  • 蓝色 : 可运行(Runnable)
  • 白色 : 休眠中(Sleep)
  • 橘色 : 不可中断的睡眠态 (Uninterruptible Sleep - IO Block)
  • 紫色 : 不可中断的睡眠态(Uninterruptible Sleep)

3.2.2 卡顿示例

  如下图所示,APP进程中’F’表示一帧,红色的’F’表示可能发生卡顿。因为在设备的渲染流程上,普遍采用了Double Buffer或Triple Buffer,所以App进程中的红色Frame并不一定代表有卡顿发生,需要结合SurfaceFlinger进程、BufferQueue的大小等一起分析,才能判断是否真正发生了卡顿。因篇幅较大,暂不深入介绍。
image.png

四、Perfetto

  Perfetto 是 Android 10 中引入的全新平台级跟踪工具,可用来从设备上收集多种性能跟踪数据(内核信息、用户空间信息、服务&内存使用信息)。Perfetto底层实现上:

  • 使用 ftrace 收集内核信息
  • 使用 atrace 收集服务和应用中的用户空间信息
  • 使用 heapprofd 收集服务和应用的本地内存使用情况信息

  Perfetto在Android 11上默认开启,如果要在Android 9 和Android 10上使用,请先输入如下命令,确保trace服务开启:

# Needed only on Android 9 (P) and 10 (Q) on non-Pixel phones. 
adb shell setprop persist.traced.enable 1

  下面继续介绍,官方提供了两种方式:命令行方式和UI方式来使用Perfetto。

4.1 命令行方式

  通过命令行方式,也有两种方法:

  1. 使用封装的tools/record_android_trace 脚本;
  2. 直接使用 /system/bin/perfetto命令;

4.1.1 record_android_trace脚本

  Perfetto官方建议使用record_android_trace脚本,这个脚本和直接运行’adb shell perfetto’命令功能一样,但是省去了设置输出文件路径等参数,并且在抓取结束后会自动用Chrome浏览器打开结果。

# 1.下载record_android_trace脚本
curl -O https://raw.githubusercontent.com/google/perfetto/master/tools/record_android_trace # 2.设置脚本执行权限
chmod u+x record_android_trace # 3.运行record_android_trace脚本
# See ./record_android_trace --help for more 
./record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb \ sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory app

  运行record_android_trace脚本后,perfecto会开始记录手机的运行信息,运行结束后,可以看到脚本会自动把结果保存到本地文件"trace_file.perfetto-trace"中,并自动用浏览器打开。结果如下图所示,与Systrace类似,可以看到设备的运行情况、APP进程的运行情况、APP内线程的状态等(如果想跟踪自己APP的方法执行顺序,详见第5章自定义事件):
image.png

4.1.2 Perfetto命令

# Perfetto命令使用方式如下:
➜  ~ adb shell perfetto [ --time TIMESPEC ] [ --buffer SIZE ] [ --size SIZE ][ ATRACE_CAT | FTRACE_GROUP/FTRACE_NAME | FTRACE_GROUP/* ]
# Perfetto的更多参数可以参考:https://developer.android.com/studio/command-line/perfetto?hl=zh-cn
# perfetto可选参数
➜  ~ adb shell perfetto --help
perfetto_cmd.cc:205      --background     -d      : Exits immediately and continues tracing inbackground--config         -c      : /path/to/trace/config/file or - for stdin--out            -o      : /path/to/out/trace/file or - for stdout--dropbox           TAG  : Upload trace into DropBox using tag TAG--no-guardrails          : Ignore guardrails triggered when using --dropbox(for testing).--txt                    : Parse config as pbtxt. Not for production use.Not a stable API.--reset-guardrails       : Resets the state of the guardails and exits(for testing).--query                  : Queries the service state and prints it ashuman-readable text.--query-raw              : Like --query, but prints raw proto-encoded bytesof tracing_service_state.proto.--help           -hlight configuration flags: (only when NOT using -c/--config)--time           -t      : Trace duration N[s,m,h] (default: 10s)--buffer         -b      : Ring buffer size N[mb,gb] (default: 32mb)--size           -s      : Max file size N[mb,gb] (default: in-memory ring-buffer only)ATRACE_CAT               : Record ATRACE_CAT (e.g. wm)FTRACE_GROUP/FTRACE_NAME : Record ftrace event (e.g. sched/sched_switch)FTRACE_GROUP/*           : Record all events in group (e.g. sched/*)statsd-specific flags:--alert-id           : ID of the alert that triggered this trace.--config-id          : ID of the triggering config.--config-uid         : UID of app which registered the config.--subscription-id    : ID of the subscription that triggered this trace.Detach mode. DISCOURAGED, read https://docs.perfetto.dev/#/detached-mode :--detach=key          : Detach from the tracing session with the given key.--attach=key [--stop] : Re-attach to the session (optionally stop tracing once reattached).--is_detached=key     : Check if the session can be re-attached (0:Yes, 2:No, 1:Error).

  例如在命令行输入如下信息:

# 1.命令行输入如下信息:
# 其中:dalvik app sched idle frep load view 表示perfetto使用atrace抓取的信息类型
# --time 5s表示:抓取时长5s
# --out 表示:perfetto运行的结果输出到该文件
> adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s \
sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory app# 开始运行后,可以看到命令行提示如下信息:
[032.653] perfetto_cmd.cc:792     Connected to the Perfetto traced service, TTL: 5s
[037.695] perfetto_cmd.cc:916     Wrote 4370324 bytes into /data/misc/perfetto-traces/trace# 2.运行结束后,可以输入如下命令,把perfecto结果从手机上拉到电脑上
> adb pull /data/misc/perfetto-traces/bc_perfetto_trace ./bc_perfetto_trace

  在把perfetto的trace结果保存到本地后,用chrome浏览器打开"https://ui.perfetto.dev "可视化界面操作,然后打开trace文件如下图所示:
image.png

4.2 UI界面

  Chrome浏览器打开"https://ui.perfetto.dev/#!/record "可视化界面操作,如右下所示可以看到底层也是通过"adb shell perfetto"实现抓取。
perfetto.jpeg

五、自定义事件

5.1 自定义JAVA事件

  在 Android 4.3(API 级别 18)及更高版本中,您可以在代码中使用 Trace 类来定义随后会出现在 Perfetto 和 Systrace 报告中的自定义事件。在自定义事件的起点和终点分别调用Trace.beginSection()Trace.endSection(),如以下代码段所示:

// 自定义事件的起点
Trace.beginSection("BC blurBitmap");
// ...省略部分代码,起点和终点间的代码会作为一个"BC blurBitmap"事件被统计
// 自定义事件的终点
Trace.endSection();
// 注意必须在同一个线程上调用这两个方法,不能在一个线程上调用 beginSection(),而在另一个线程上结束它

5.2 自定义native事件

  对于native代码,Android 6.0(API 级别 23)及更高版本提供了native跟踪 API trace.h头文件,在自定义事件的起点和终点分别调用ATrace_beginSection()ATrace_endSection(),如下所示:

    #include <android/trace.h>char *customEventName = new char[32];sprintf(customEventName, "User tapped %s button", buttonName);// 自定义事件起点ATrace_beginSection(customEventName);// 省略native代码...// 自定义事件终点ATrace_endSection(); 

5.3 自定义事件例子

  在1.2中的例子,自定义java事件(“BC blurBitmap”)如下所示:

public class OpenCVActivity2  extends Activity implements View.OnClickListener {private Bitmap blurBitmap(Bitmap bitmap) {// 自定义事件"BC blurBitmap"的起点Trace.beginSection("BC blurBitmap");Bitmap result = OpenCVSample.blurBitmap(bitmap, 30);// 自定义事件"BC blurBitmap"的终点Trace.endSection();return result;}@Overridepublic void onClick(View v) {if (v.getId() == R.id.opencv_sample_button) {Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.adventure_time);Bitmap bitmap1 = blurBitmap(bitmap);imageView1.setImageBitmap(bitmap1);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}  
}

  在自定义事件后,在使用Systrace和Perfetto时就可以看到app内的自定义事件执行情况。

5.3.1 Systrace自定义事件

  运行Systrace时,注意需要加上"-a com.bc.example"才会生效:

➜ ~ python /Users/bc/Library/Android/sdk/platform-tools/systrace/systrace.py -a 
com.bc.example -b 16384 -o my_systrace_report.html app load view

  运行结果如下,可以看到方法跟踪的结果显示了自定义事件"BC blurBitmap"的运行情况:
image.png

5.3.2 Perfetto自定义事件

  (1)首先,本地新建一个文件’bc_example.cfg’用来存放Perfetto配置,如下所示:

buffers: {size_kb: 522240fill_policy: DISCARD
}
data_sources: {config {name: "linux.ftrace"ftrace_config {ftrace_events: "sched/sched_switch"atrace_categories: "dalvik"atrace_categories: "view"atrace_apps: "com.bc.example"}}
}
duration_ms: 10000

  (2)然后,运行4.1.1小节的record_android_trace脚本,并使用’-c’指定配置文件:

./record_android_trace -c bc_example.cfg -o trace_file.perfetto-trace

  运行后的结果如下图所示,同样可以看到自定义事件"BC blurBitmap"的运行情况:
image.png

5.3.3 常见问题

(1)部分手机Systrace抓到的trace看不到APP内的方法跟踪,这是因为部分手机不支持抓取app类型的trace信息,可以换个手机试下。另外,可以通过如下命令查看机器支持Systrace的类型:

python systrace.py -l

(2)实际开发中,每个方法中都手动加入Trace自定义事件比较麻烦,可以尝试开发一个gradle脚本来完成Trace插桩。

(3)使用Systrace抓APP的方法执行顺序,要求App必须是debuggable的,如果要在release包中开启自定义事件,需要用到反射打开Trace功能:

Class<?> trace = Class.forName("android.os.Trace");
Method setAppTracingAllowed = trace.getDeclaredMethod("setAppTracingAllowed", boolean.class);
setAppTracingAllowed.invoke(null, true);

六、"系统跟踪"应用

  "系统跟踪"应用是Android手机上的一个功能,其原理类似于 Systrace 或 Perfetto 命令行。通过"系统跟踪"应用,开发者可以直接从测试设备本身录制跟踪记录,而无需插入设备并通过命令行操作。

  如下图所示,"系统跟踪"应用位于开发者选项 - 调试 - System Tracing下,或者也可以在打开"开发者选项"后通过如下命令行启动"系统跟踪"应用,但是国内很多设备都没有该功能应用,暂不详细介绍。

adb shell am start com.android.traceur/com.android.traceur.MainActivity

system tracing.jpeg
  在Android 10(API 级别 29)或更高版本的设备上,"系统跟踪"应用的跟踪文件会使用 ‘.perfetto-trace’ 文件扩展名保存到/data/local/traces/目录下,并可在 Perfetto 界面中打开。在较旧 Android 版本的设备上,跟踪文件会使用 ‘.ctrace’ 文件扩展名(表示 Systrace 格式)保存。之后就可以把perfetto或trace文件分别用对应工具打开进行分析优化。

七、工具选择

  1. CPU性能剖析器的方法跟踪信息可以帮助您找出应用中用时最多的方法,帮助您定位并针对性分析优化。使用比较方便,但是方法跟踪不适合用于识别卡顿,因为它们会因开销过大而导致出现假正例卡顿,且无法查看线程何时运行以及何时处于阻塞状态。
  2. Systrace和Perfetto性能损耗小,在结果页的展示上,Perfetto相比更Systrace体验更流畅一些。
  3. Perfetto支持SQL查询,方便开发者根据sql条件快速筛选出数据,开发者可以结合官方示例扩展开发自身业务需要的自动化分析脚本等。
  4. Perfetto只支持Android 10及更高版本的设备,且官方提供的脚本使用便捷,结果查找方便;建议Android 10 以上设备直接使用Perfetto。

The End

欢迎关注我,一起解锁更多技能:BC的掘金主页~💐 BC的CSDN主页~💐💐
请添加图片描述

系统跟踪概览:https://developer.android.com/topic/performance/tracing/?hl=zh-cn

Android Studio Profiler文档:https://developer.android.com/studio/profile/android-profiler?hl=zh-cn

systrace命令:https://developer.android.com/topic/performance/tracing/command-line?hl=zh-cn

perfetto命令:https://developer.android.com/studio/command-line/perfetto?hl=zh-cn

"系统跟踪"应用:https://developer.android.com/topic/performance/tracing/on-device?hl=zh-cn

ftrace文档:https://source.android.com/devices/tech/debug/ftrace?hl=zh-cn

Systrace参考文档:https://www.androidperformance.com/2019/05/28/Android-Systrace-About/


http://chatgpt.dhexx.cn/article/K3VH1gjQ.shtml

相关文章

搭建Babel运行环境,Traceur ES6模板,块级作用域,let和const命令

搭建Babel运行环境 Babel&#xff08;http://babeljs.io/&#xff09;可用于将使用ES6语法的脚本转化为ES5语法的脚本&#xff0c;基本功能的安装步骤如下&#xff1a; 1、安装node解释器和npm包管理工具 2、安装babel解释器 npm install -g babel &#xff08;建议这个过程完…

ES6转ES5,Traceur使用方式

ES6于2015年6月正式发布&#xff0c;各大浏览器的最新版本对 ES6 的支持可以查看https://kangax.github.io/compat-table/es6/。 目前各大浏览器和开发环境对支持ES6的支持情况参差不齐&#xff0c;在实际项目开发中&#xff0c;我们仍旧不得不降级使用ES5语法以兼容各平台。幸…

Traceur 使用方式

ES6于2015年6月正式发布&#xff0c;各大浏览器的最新版本对 ES6 的支持可以查看https://kangax.github.io/compat-table/es6/。 目前各大浏览器和开发环境对支持ES6的支持情况参差不齐&#xff0c;在实际项目开发中&#xff0c;我们仍旧不得不降级使用ES5语法以兼容各平台。幸…

Rxjava:interval的使用

以固定的时间间隔不断发射数据。 测试&#xff1a; Test public void testSimple(){Observable.interval(1, TimeUnit.SECONDS).subscribe(new Action1<Long>() {Overridepublic void call(Long aLong) {System.out.println("aLong " aLong);}});for (;;){…

FlinkSql系列6之 Interval Join

FlinkSql系列6之 Interval Join 前言 本次我们来学习flinksql的Interval Join,这个方式主要是针对两个流在一定时间区间内的join,支持事件时间和处理时间&#xff0c;而且这个流每次只会产生一条数据&#xff0c;是一个完全的追加流。 一、Interval Join是什么&#xff1f; I…

Flink Interval Join使用以及源码解析

1、Interval Join 概述 在之前的Join算子中&#xff0c;一般使用的是coGroup算子&#xff0c;因为一个算子可以提供多种语义&#xff0c;但是也是有一些弊端的。因为coGroup只能实现在同一个窗口的两个数据流之间进行join&#xff0c;在实际的计算过程中&#xff0c;往往会遇到…

mysql datesub interval_Mysql之INTERVAL与DATE_SUB与EXTRACT函数的使用

1. INTERVAL INTERVAL代表的是时间间隔 MySQL中的时间间隔类型有如下几种: 1.1 利用INTERVAL做时间的加减法 示例: 加法:SQL>SELECT DATE 2018-11-01 + INTERVAL 10 11 DAY_HOUR; 结果:2018-11-11 11:00:00 减法:SQL> select date 2018-11-11 11:00:00 -INTERVAL 10 11…

ORACLE中的INTERVAL

ORACLE中的INTERVAL 关于INTERVALINTERVAL类型INTERVAL YEAR TO MONTHINTERVAL DAY TO SECOND 关于INTERVAL oracle中提供了两种日期时间类型&#xff0c;分别是DATE和TIMESTAMP用来存储时间点的数据&#xff0c;同时还提供了INTERVAL来存储一段时间的数据。例如你2022年11月1…

Flink SQL之Interval Joins

1.Interval Joins&#xff08;区间Join&#xff09; 区间是双流join的优化&#xff0c;基于处理时间或事件时间&#xff0c;在一定时间区间内数据&#xff0c;相同的key进行join&#xff08;支持 Batch\Streaming&#xff09;。Interval Join 可以让一条流去 Join 另一条流中前…

MySQL INTERVAL 关键字指南

在本教程中&#xff0c;我们将了解 MySQL INTERVAL 关键字及其值以对日期和时间算术执行操作。那么&#xff0c;让我们开始吧&#xff01; 另请阅读&#xff1a;MySQL 中的 While 循环 – 完整参考 MySQL INTERVAL 简介 在 MySQL 中&#xff0c;INTERVAL 关键字用于添加或减…

Flink之IntervalJoin介绍

InterValJoin算子 间隔流&#xff0c;一条流去join另一条流去过去一段时间内的数据&#xff0c;该算子将keyedStream与keyedStream转化为DataStream&#xff1b;再给定的时间边界内&#xff08;默认包含边界&#xff09;&#xff0c;相当于一个窗口&#xff0c;按指定的key对俩…

Mysql的INTERVAL()函数和INTERVAL关键字

一&#xff0c;INTERVAL()函数 INTERVAL()函数可以返回分段后的结果&#xff0c;语法如下&#xff1a; INTERVAL(N,N1,N2,N3,..........) 其中&#xff0c;N是要判断的数值&#xff0c;N1,N2,N3,...是分段的间隔。 这个函数的返回值是段的位置&#xff1a; 如果N<N1&am…

Mysql_interval函数与关键字

目录 一、统计不同区间的数量&#xff1a;INTERVAL()函数 二、时间间隔&#xff1a;INTERVAL关键字 一、统计不同区间的数量&#xff1a;INTERVAL()函数 INTERVAL()函数可以返回分段后的结果&#xff0c;语法如下&#xff1a; INTERVAL(N,N1,N2,N3,......,Nn) 其中&#x…

INTERVAL记录

INTERVAL作为sql中关键字 interval在sql中一般表示为时间间隔的意思 常用在date_add()、**date_sub()**函数中&#xff0c;常用于时间的加减法 上述sql表示为当前时间一年后的时间。 interval后可选择的时间粒度&#xff1a; MICROSECOND&#xff0c; SECOND&#xff0c; MIN…

万能的Attention及其代码实现

最近看到以前的代码&#xff0c;想到了attention&#xff0c;趁着代码还在就来整理一下。 文章目录 [Squeeze-and-Excitation Networks](https://arxiv.org/abs/1709.01507)[Concurrent Spatial and Channel ‘Squeeze &Excitation’ in Fully Convolutional Networks](ht…

NLP中的Attention总结

Attention是模拟人脑的注意力机制。人在看到一些东西&#xff0c;往往只关注重要的信息&#xff0c;而忽略其他信息。自然语言处理中的attention是对文本分配注意力权重&#xff0c;Attention的本质就是从关注全部变为关注重点。 1 Attention的原理 Attention的计算过程&#…

Attention 理解汇总

在 Encoder-Decoder中&#xff0c;预测每个Decoder 的语义编码 c 是一样的&#xff0c;句子 X 中每个词对输出 Y 的每个词的影响都是相同的。 这样有两个弊端&#xff1a; 一是语义向量无法完全表示整个序列的信息&#xff1b; 二是先输入的内容携带的信息会被后输入的信息稀…

[深度学习] 自然语言处理 --- Self-Attention(三) 知识点与源码解析

在当前的 NLP 领域&#xff0c;Transformer / BERT 已然成为基础应用&#xff0c;而 Self-Attention 则是两者的核心部分&#xff0c;下面尝试用 Q&A 和源码的形式深入 Self-Attention 的细节。 一 Q&A 1. Self-Attention 的核心是什么&#xff1f; Self-Attention …

attention介绍

Attention 正在被越来越广泛的得到应用。 Attention 到底有什么特别之处&#xff1f;他的原理和本质是什么&#xff1f;Attention都有哪些类型&#xff1f;本文将详细讲解Attention的方方面面。 Attention 的本质是什么 Attention&#xff08;注意力&#xff09;机制如果浅层…

Attention原理

文章目录 Attention原理HAN原理利用Attention模型进行文本分类参考资料 Attention原理 转载一个Hierarchical Attention神经网络的实现 转载 图解Transformer 转载 Attention原理和源码解析 论文链接 Attention is All You Need HAN原理 论文链接Hierarchical Attention Net…