无论您捕获的是应用驱动的配置文件还是基于触发器的配置文件,ProfilingManager 都会将完成的文件保存在设备上,并向您注册的回调传送 ProfilingResult。调用 ProfilingResult.getResultFilePath 以获取已保存配置文件的路径:
- 在本地测试期间:使用
adb将文件拉取到您的计算机。 - 在生产环境中:传递
WorkManager作业的路径,该作业会压缩配置文件并将其上传到您的服务器。
从设备中检索配置文件
本部分介绍了 ProfilingManager 在设备上存储配置文件的位置、自动文件清理的工作原理,以及如何使用 adb 在本地拉取文件。
文件位置和命名格式
ProfilingManager 会将经过隐去处理的配置文件保存在 /data/user/0/<app>/files/profiling/ 的应用专属存储目录中。文件名格式取决于配置文件的捕获方式:
应用驱动的配置文件:
profile_<tag>_<datetime>_uid-<uid>.<profile-type-ext>如果在请求配置文件时未提供标记,则会省略
<tag>_:profile_<datetime>_uid-<uid>.<profile-type-ext>。基于触发器的配置文件:
profile_trigger-type-<trigger_type>_<datetime>_uid-<uid>.<profile-type-ext>
其中:
<app>是应用的软件包名称。<tag>是使用setTag配置或传递给requestProfiling的调用方提供的标记的前 20 个字母数字字符(和连字符),转换为小写,并移除了a-z、0-9和-之外的所有字符。<trigger_type>是ProfilingTrigger中触发器的整数常量代码。始终在代码中调用ProfilingResult.getTriggerType,而不是解析文件名。<datetime>是记录性能剖析文件的日期和时间 (yyyy-MM-dd-HH-mm-ss-SSS)。<uid>是应用的 Linux 用户 ID(包含在最近的Profiling模块版本中)。<profile-type-ext>是所捕获性能剖析类型的文件扩展名:.perfetto-trace(适用于系统跟踪).perfetto-java-heap-dump,适用于 Java 堆转储.perfetto-heap-profile(针对堆分析报告).perfetto-stack-sample,适用于堆栈采样配置文件
设备端存储和清理
为了及时释放设备存储空间,请在每次成功上传后立即删除上传工作器中的每个配置文件(因为自动清理仅在 ProfilingManager 向应用提供结果时运行,否则,如果应用在结束广告系列后停止注册回调,未上传的文件可能会保留在磁盘上)。作为近期 Profiling 模块版本的后备方案,ProfilingManager 也会在提供新结果时自动删除应用专用存储目录中超过 5 天的已提供文件。
在正式版中使用 WorkManager 上传配置文件
由于配置文件的大小可能达到几兆字节,因此请在设备处于不按流量计费的网络 (Wi-Fi) 中、正在充电且处于空闲状态时,在后台安排正式版上传。
在上传之前,请压缩配置文件(例如,使用 GZIPOutputStream 或 ZipOutputStream)。Perfetto protobuf 配置文件和 Java 堆转储会显著压缩,从而降低网络带宽和后端存储费用。
添加 WorkManager 依赖项
ProfilingManager 与云无关,因此您可以使用 WorkManager 安排将配置文件上传到任何后端。将 WorkManager 库添加到 build.gradle.kts 文件中:
Kotlin
dependencies { implementation("androidx.work:work-runtime:2.12.0") }
Groovy
dependencies { implementation 'androidx.work:work-runtime:2.12.0' }
安排上传作业
当您的应用收到 ProfilingResult 时,请安排上传作业。以下示例省略了初始性能分析请求;如需查看完整的请求示例,请参阅记录系统跟踪记录。
Kotlin
class TraceUploadWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { override fun doWork(): Result { // Perform your uploading work here Log.d("ProfileTest", "Uploading trace: " + inputData.getString("PROFILE_PATH")) return Result.success() } } fun setupProfileUploadWorker(profileFilepath: String?) { val workMgr = WorkManager.getInstance(applicationContext) val workRequestBuilder = OneTimeWorkRequest.Builder(TraceUploadWorker::class) val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresDeviceIdle(true) .setRequiresCharging(true) .build() workRequestBuilder.setConstraints(constraints) val inputDataBuilder = Data.Builder() inputDataBuilder.putString("PROFILE_PATH", profileFilepath) workRequestBuilder.setInputData(inputDataBuilder.build()) workMgr.enqueue(workRequestBuilder.build()) }
Java
public static class TraceUploadWorker extends Worker { public TraceUploadWorker( @androidx.annotation.NonNull Context context, @androidx.annotation.NonNull WorkerParameters workerParams) { super(context, workerParams); } @androidx.annotation.NonNull @Override public Result doWork() { // Perform your uploading work here Log.d("ProfileTest", "Uploading trace: " + getInputData().getString("PROFILE_PATH")); return Result.success(); } } public void setupProfileUploadWorker(String profileFilepath) { WorkManager workMgr = WorkManager.getInstance(getApplicationContext()); OneTimeWorkRequest.Builder workRequestBuilder = new OneTimeWorkRequest.Builder( TraceUploadWorker.class); Constraints constraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresDeviceIdle(true) .setRequiresCharging(true) .build(); workRequestBuilder.setConstraints(constraints); Data.Builder inputDataBuilder = new Data.Builder(); inputDataBuilder.putString("PROFILE_PATH", profileFilepath); workRequestBuilder.setInputData(inputDataBuilder.build()); workMgr.enqueue(workRequestBuilder.build()); }
代码演示
上述示例执行以下步骤:
- 定义工作器:创建一个扩展
Worker的TraceUploadWorker类。实现doWork,以验证配置文件是否仍然存在,使用后端 SDK 或 HTTP 客户端对其进行压缩和上传,并在上传成功后删除本地文件。 - 安排工作:
- 为您的 worker 创建
OneTimeWorkRequest。 - 设置限制:使用
setRequiredNetworkType(NetworkType.UNMETERED)、setRequiresDeviceIdle(true)和setRequiresCharging(true),以便仅在设备连接到 Wi-Fi、正在充电且处于空闲状态时才运行上传。 - 传递数据:使用
setInputData将配置文件路径从getResultFilePath传递给工作器。 - 加入队列:通过调用
WorkManager.enqueue将请求提交到WorkManager。
- 为您的 worker 创建
后续步骤
检索或上传配置文件后,在 Perfetto 界面中直观呈现这些配置文件、使用 PerfettoSQL 查询单个配置文件、批量分析跟踪记录或使用 AI 分析配置文件。如需有关设置可扩缩的服务器端分析流水线的指导,请参阅在 Kubernetes 上部署 Bigtrace。