Halaman ini menunjukkan cara merekam rekaman aktivitas sistem menggunakan ProfilingManager API.
ProfilingManager juga dapat merekam jenis profil lainnya. Proses ini mirip dengan merekam aktivitas sistem, tetapi setiap jenis menggunakan builder yang berbeda. Profil yang didukung dan builder-nya adalah:
Rekaman Aktivitas Sistem: Direkam menggunakan
SystemTraceRequestBuilder, yang berguna untuk analisis latensi dan proses debug performa umum.Heap dump: Direkam menggunakan
JavaHeapDumpRequestBuilder, yang berguna untuk mendeteksi dan mengoptimalkan kebocoran memori.Profil heap: Direkam menggunakan
HeapProfileRequestBuilder, yang berguna untuk pengoptimalan memori.Profil stack panggilan: Direkam menggunakan
StackSamplingRequestBuilder, yang berguna untuk memahami eksekusi kode dan analisis latensi.
Menambahkan dependensi
Untuk mendapatkan pengalaman terbaik dengan ProfilingManager API, tambahkan library Jetpack berikut ke file build.gradle.kts Anda.
Kotlin
dependencies { implementation("androidx.tracing:tracing-ktx:2.0.2") implementation("androidx.core:core:1.19.0") }
Groovy
dependencies { implementation 'androidx.tracing:tracing:2.0.2' implementation 'androidx.core:core:1.19.0' }
Merekam pelacakan sistem
Setelah menambahkan dependensi yang diperlukan, gunakan kode berikut untuk merekam rekaman aktivitas sistem. Contoh ini menunjukkan cara memulai sesi pembuatan profil dari composable sambil mengelola operasi berat dengan aman di luar thread utama.
Kotlin
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@Composable
fun ProfiledScreen(modifier: Modifier = Modifier) {
// Use the application context: requestProfiling resolves the ProfilingManager
// system service from it, so there's no reason to hand it a short-lived Activity.
val appContext = LocalContext.current.applicationContext
val scope = rememberCoroutineScope()
Button(
onClick = {
// Run the orchestration off the main thread. Profiling a heavy operation
// on the UI thread would freeze the UI (ANR) and distort the very metrics
// you're trying to capture.
//
// Note: this scope is tied to composition. If the user leaves this screen
// mid-session, the coroutine is cancelled and stopSignal.cancel() might not
// run, but setDurationMs() acts as a safety net and ends the trace.
scope.launch(Dispatchers.Default) {
val callbackExecutor = Dispatchers.IO.asExecutor()
val resultCallback = Consumer<ProfilingResult> { profilingResult ->
if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
Log.d("ProfileTest", "Result file: ${profilingResult.resultFilePath}")
} else {
// errorMessage explains the failure (e.g., rate limiting); keep it.
Log.e(
"ProfileTest",
"Profiling failed errorCode=${profilingResult.errorCode} " +
"errorMessage=${profilingResult.errorMessage}"
)
}
}
val stopSignal = CancellationSignal()
val requestBuilder = SystemTraceRequestBuilder().apply {
setCancellationSignal(stopSignal)
setTag("FOO") // Caller-supplied tag for identification.
setDurationMs(60000) // Hard cap: ends the session if cancel() never fires.
setBufferFillPolicy(BufferFillPolicy.RING_BUFFER)
setBufferSizeKb(32768)
}
// 1. Start the session. This is asynchronous system IPC. The tracing
// engine takes a moment to start and allocate buffers.
requestProfiling(appContext, requestBuilder.build(), callbackExecutor, resultCallback)
// 2. The API exposes no "profiling started" signal, so pad with a short,
// best-effort delay before running the code you care about. This is
// approximate. Increase it on slower or heavily loaded devices.
delay(STARTUP_PADDING_MS)
// 3. The session is already recording every thread in your app. This slice
// doesn't scope what's captured. It just labels this region of the
// timeline so heavyOperation() is easier to find. trace { } closes the
// section even if the block throws.
trace("MyApp:HeavyOperation") {
heavyOperation()
}
// 4. Stop recording. Until this fires or the setDurationMs() cap is
// reached (whichever comes first), the session keeps capturing app-wide
// activity.
stopSignal.cancel()
}
}
) {
Text("Run & Profile Heavy Operation")
}
}
// Best-effort wait for the system trace engine to initialize before profiling.
// There is no deterministic start callback; tune this for your target devices.
private const val STARTUP_PADDING_MS = 100L
fun heavyOperation() {
// Background computations to profile.
}
Java
void heavyOperation() {
// Computations you want to profile
}
void sampleRecordSystemTrace() {
Executor mainExecutor = Executors.newSingleThreadExecutor();
Consumer<ProfilingResult> resultCallback =
new Consumer<ProfilingResult>() {
@Override
public void accept(ProfilingResult profilingResult) {
if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) {
Log.d(
"ProfileTest",
"Received profiling result file=" + profilingResult.getResultFilePath());
setupProfileUploadWorker(profilingResult.getResultFilePath());
} else {
Log.e(
"ProfileTest",
"Profiling failed errorcode="
+ profilingResult.getErrorCode()
+ " errormsg="
+ profilingResult.getErrorMessage());
}
}
};
CancellationSignal stopSignal = new CancellationSignal();
SystemTraceRequestBuilder requestBuilder = new SystemTraceRequestBuilder();
requestBuilder.setCancellationSignal(stopSignal);
requestBuilder.setTag("FOO");
requestBuilder.setDurationMs(60000);
requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER);
requestBuilder.setBufferSizeKb(32768);
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 profile
stopSignal.cancel();
}
Kode contoh menyiapkan dan mengelola sesi pembuatan profil dengan melakukan langkah-langkah berikut:
Siapkan eksekutor. Buat
Executoruntuk menentukan thread yang akan menerima hasil pembuatan profil. Pembuatan profil terjadi di latar belakang. Menggunakan eksekutor thread non-UI membantu mencegah error Aplikasi Tidak Merespons (ANR) jika Anda menambahkan lebih banyak pemrosesan ke callback nanti.Menangani hasil pembuatan profil. Buat objek
Consumer<ProfilingResult>. Sistem menggunakan objek ini untuk mengirim hasil pembuatan profil dariProfilingManagerkembali ke aplikasi Anda.Buat permintaan pembuatan profil. Buat
SystemTraceRequestBuilderuntuk menyiapkan sesi pembuatan profil Anda. Builder ini memungkinkan Anda menyesuaikan setelan rekaman aktivitasProfilingManager. Penyesuaian builder bersifat opsional; jika Anda tidak melakukannya, sistem akan menggunakan setelan default.- Tentukan tag. Gunakan
setTag()untuk menambahkan tag ke nama rekaman aktivitas. Tag ini membantu Anda mengidentifikasi rekaman aktivitas. - Opsional: Tetapkan durasi. Gunakan
setDurationMs()untuk menentukan durasi pemrofilan dalam milidetik. Misalnya,60000menetapkan rekaman aktivitas 60 detik. Perekaman aktivitas akan otomatis berakhir setelah durasi yang ditentukan jikaCancellationSignaltidak dipicu sebelumnya. - Pilih kebijakan buffer. Gunakan
setBufferFillPolicy()untuk menentukan cara penyimpanan data rekaman aktivitas.BufferFillPolicy.RING_BUFFERberarti bahwa saat buffer penuh, data baru akan menggantikan data terlama, sehingga mencatat aktivitas terbaru secara berkelanjutan. - Tetapkan ukuran buffer. Gunakan
setBufferSizeKb()untuk menentukan ukuran buffer untuk merekam aktivitas yang dapat Anda gunakan untuk mengontrol ukuran file rekaman aktivitas output.
- Tentukan tag. Gunakan
Opsional: Kelola siklus proses sesi. Buat
CancellationSignal. Objek ini memungkinkan Anda menghentikan sesi pembuatan profil kapan pun Anda mau, sehingga Anda memiliki kontrol yang presisi atas durasinya.Mulai dan terima hasil. Saat Anda memanggil
requestProfiling(),ProfilingManagerakan memulai sesi pembuatan profil di latar belakang. Setelah pembuatan profil selesai,ProfilingResultakan dikirim ke metoderesultCallback#acceptAnda. Jika pembuatan profil berhasil diselesaikan,ProfilingResultakan memberikan jalur tempat rekaman aktivitas disimpan di perangkat Anda melaluiProfilingResult#getResultFilePath. Anda bisa mendapatkan file ini secara terprogram atau, untuk pembuatan profil lokal, dengan menjalankanadb pull <trace_path>dari komputer Anda.Tambahkan titik rekaman aktivitas kustom. Anda dapat menambahkan titik rekaman aktivitas kustom dalam kode aplikasi Anda. Dalam contoh kode sebelumnya, blok
trace("MyApp:HeavyOperation") { ... }membuat slice kustom dalam profil yang dihasilkan.