@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)funsampleRecordSystemTrace(){valmainExecutor:Executor=Dispatchers.IO.asExecutor()// Your choice of executor for the callback to occur on.valresultCallback=Consumer<ProfilingResult>{profilingResult->
if(profilingResult.errorCode==ProfilingResult.ERROR_NONE){Log.d("ProfileTest","Received profiling result file="+profilingResult.resultFilePath)}else{Log.e("ProfileTest","Profiling failed errorcode="+profilingResult.errorCode+" errormsg="+profilingResult.errorMessage)}}valstopSignal=CancellationSignal()valrequestBuilder=SystemTraceRequestBuilder()requestBuilder.setCancellationSignal(stopSignal)requestBuilder.setTag("FOO")// Caller supplied tag for identificationrequestBuilder.setDurationMs(60000)requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER)requestBuilder.setBufferSizeKb(20971520)requestProfiling(applicationContext,requestBuilder.build(),mainExecutor,resultCallback)// Wait some time for profiling to start.Trace.beginSection("MyApp:HeavyOperation")heavyOperation()Trace.endSection()// Once the interesting code section is profiled, stop profilestopSignal.cancel()}funheavyOperation(){// Computations you want to profile}
voidheavyOperation(){// Computations you want to profile}voidsampleRecordSystemTrace(){ExecutormainExecutor=Executors.newSingleThreadExecutor();Consumer<ProfilingResult>resultCallback=newConsumer<ProfilingResult>(){@Overridepublicvoidaccept(ProfilingResultprofilingResult){if(profilingResult.getErrorCode()==ProfilingResult.ERROR_NONE){Log.d("ProfileTest","Received profiling result file="+profilingResult.getResultFilePath());}else{Log.e("ProfileTest","Profiling failed errorcode="+profilingResult.getErrorCode()+" errormsg="+profilingResult.getErrorMessage());}}};CancellationSignalstopSignal=newCancellationSignal();SystemTraceRequestBuilderrequestBuilder=newSystemTraceRequestBuilder();requestBuilder.setCancellationSignal(stopSignal);requestBuilder.setTag("FOO");requestBuilder.setDurationMs(60000);requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER);requestBuilder.setBufferSizeKb(20971520);Profiling.requestProfiling(getApplicationContext(),requestBuilder.build(),mainExecutor,resultCallback);// Wait some time for profiling to start.Trace.beginSection("MyApp:HeavyOperation");heavyOperation();Trace.endSection();// Once the interesting code section is profiled, stop profilestopSignal.cancel();}
[null,null,["最后更新时间 (UTC):2025-09-11。"],[],[],null,["This page shows how to record a system trace using the `ProfilingManager` API.\n| **Tip:** `ProfilingManager` contains a rate limiter that is set up to reduce the impact of repeated profiling requests on device performance. When you're using this tool locally, you want to see every request so we recommend keeping the [rate limiter enabled](/topic/performance/tracing/profiling-manager/debug-mode#disable-rate-limiter).\n\nAdd dependencies\n\nFor the best experience with the `ProfilingManager` API, add the following\nJetpack libraries to your `build.gradle.kts` file. \n\nKotlin \n\n```kotlin\n dependencies {\n implementation(\"androidx.tracing:tracing:1.3.0\")\n implementation(\"androidx.core:core:1.17.0\")\n }\n \n```\n\nGroovy \n\n```groovy\n dependencies {\n implementation 'androidx.tracing:tracing:1.3.0'\n implementation 'androidx.core:core:1.17.0'\n }\n \n```\n\nRecord a system trace\n\nAfter adding the required dependencies, use the following code to record a\nsystem trace. This example shows a basic setup within an `Activity` to start and\nmanage a profiling session.\n\n\nKotlin \n\n```kotlin\n@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)\nfun sampleRecordSystemTrace() {\n val mainExecutor: Executor =\n Dispatchers.IO.asExecutor() // Your choice of executor for the callback to occur on.\n val resultCallback = Consumer\u003cProfilingResult\u003e { profilingResult -\u003e\n if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {\n Log.d(\n \"ProfileTest\",\n \"Received profiling result file=\" + profilingResult.resultFilePath\n )\n } else {\n Log.e(\n \"ProfileTest\",\n \"Profiling failed errorcode=\" + profilingResult.errorCode + \" errormsg=\" + profilingResult.errorMessage\n )\n }\n }\n val stopSignal = CancellationSignal()\n\n val requestBuilder = SystemTraceRequestBuilder()\n requestBuilder.setCancellationSignal(stopSignal)\n requestBuilder.setTag(\"FOO\") // Caller supplied tag for identification\n requestBuilder.setDurationMs(60000)\n requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER)\n requestBuilder.setBufferSizeKb(20971520)\n requestProfiling(applicationContext, requestBuilder.build(), mainExecutor, resultCallback)\n\n // Wait some time for profiling to start.\n\n Trace.beginSection(\"MyApp:HeavyOperation\")\n heavyOperation()\n Trace.endSection()\n\n // Once the interesting code section is profiled, stop profile\n stopSignal.cancel()\n}\n\nfun heavyOperation() {\n // Computations you want to profile\n}https://github.com/android/snippets/blob/292ef1d272c0bc68a2d226871394065a97b06795/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt#L43-L82\n```\n\nJava \n\n```java\nvoid heavyOperation() {\n // Computations you want to profile\n}\n\nvoid sampleRecordSystemTrace() {\n Executor mainExecutor = Executors.newSingleThreadExecutor();\n Consumer\u003cProfilingResult\u003e resultCallback =\n new Consumer\u003cProfilingResult\u003e() {\n @Override\n public void accept(ProfilingResult profilingResult) {\n if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) {\n Log.d(\n \"ProfileTest\",\n \"Received profiling result file=\" + profilingResult.getResultFilePath());\n } else {\n Log.e(\n \"ProfileTest\",\n \"Profiling failed errorcode=\"\n\n + profilingResult.getErrorCode()\n + \" errormsg=\"\n + profilingResult.getErrorMessage());\n }\n }\n };\n CancellationSignal stopSignal = new CancellationSignal();\n\n SystemTraceRequestBuilder requestBuilder = new SystemTraceRequestBuilder();\n requestBuilder.setCancellationSignal(stopSignal);\n requestBuilder.setTag(\"FOO\");\n requestBuilder.setDurationMs(60000);\n requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER);\n requestBuilder.setBufferSizeKb(20971520);\n Profiling.requestProfiling(getApplicationContext(), requestBuilder.build(), mainExecutor,\n resultCallback);\n\n // Wait some time for profiling to start.\n\n Trace.beginSection(\"MyApp:HeavyOperation\");\n heavyOperation();\n Trace.endSection();\n\n // Once the interesting code section is profiled, stop profile\n stopSignal.cancel();\n}https://github.com/android/snippets/blob/292ef1d272c0bc68a2d226871394065a97b06795/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java#L26-L70\n```\n\n\u003cbr /\u003e\n\nThe sample code sets up and manages the profiling session by going through the\nfollowing steps:\n\n1. **Set up the executor.** Create an `Executor` to define the thread that will\n receive the profiling results. Profiling happens in the background. Using a\n non-UI thread executor helps prevent Application Not Responding (ANR) errors\n if you add more processing to the callback later.\n\n2. **Handle profiling results.** Create a `Consumer\u003cProfilingResult\u003e` object.\n The system uses this object to send profiling results from\n `ProfilingManager` back to your app.\n\n3. **Build the profiling request.** Create a `SystemTraceRequestBuilder` to set\n up your profiling session. This builder lets you customize\n `ProfilingManager` trace settings. Customizing the builder is optional; if\n you don't, the system uses default settings.\n\n - **Define a tag.** Use `setTag()` to add a tag to the trace name. This tag helps you identify the trace.\n - **Optional: Set the duration.** Use `setDurationMs()` to specify how long to profile in milliseconds. For example, `60000` sets a 60-second trace. The trace automatically ends after the specified duration if `CancellationSignal` isn't triggered before that.\n - **Choose a buffer policy.** Use `setBufferFillPolicy()` to define how trace data is stored. `BufferFillPolicy.RING_BUFFER` means that when the buffer is full, new data overwrites the oldest data, keeping a continuous record of recent activity.\n - **Set a buffer size.** Use `setBufferSizeKb()` to specify a buffer size for tracing which you can use to control the size of the output trace file.\n\n | **Note:** Not all the Perfetto configurations are available for `ProfilingManager`.\n4. **Optional: Manage the session lifecycle.** Create a `CancellationSignal`.\n This object lets you stop the profiling session whenever you want, giving\n you precise control over its length.\n\n | **Note:** If you use neither `CancellationSignal` nor `setDurationMs()`, the system applies a default duration. If you define both, whichever happens first ends the session.\n5. **Start and receive results.** When you call `requestProfiling()`,\n `ProfilingManager` starts a profiling session in the background. Once\n profiling is done, it sends the `ProfilingResult` to your\n `resultCallback#accept` method. If profiling finishes successfully, the\n `ProfilingResult` provides the path where the trace was saved on your device\n through `ProfilingResult#getResultFilePath`. You can get this file\n programmatically or, for local profiling, by running `adb pull \u003ctrace_path\u003e`\n from your computer.\n\n | **Note:** If an error occurs during profiling, the `ProfilingResult` provides an error description through `profilingResult.getErrorMessage()` and an error code through `profilingResult.getErrorCode()`. A common reason for failure is if your app gets rate limited due to excessive requests.\n | **Note:** If the app dies before this result is delivered, delivery will be attempted again once the app starts and registers a general listener.\n6. **Add custom trace points.** You can add custom trace points in your app's\n code. In the previous code example, a trace slice named\n `MyApp:HeavyOperation` is added using `Trace.beginSection()` and\n `Trace.endSection()`. This custom slice appears in the generated profile,\n highlighting specific operations within your app."]]