ProfilingManager mendukung pengambilan profil berdasarkan pemicu sistem. Sistem mengelola proses perekaman dan memberikan profil yang dihasilkan ke aplikasi Anda.
Pemicu terkait dengan peristiwa penting performa. Profil yang direkam sistem memberikan informasi pen-debug-an mendetail untuk perjalanan penting pengguna (CUJ) yang terkait dengan pemicu ini.
Mengambil data historis
Banyak pemicu memerlukan analisis data historis yang mengarah ke peristiwa tersebut. Pemicunya sendiri sering kali merupakan konsekuensi dari masalah, bukan akar penyebabnya. Jika Anda memulai pembuatan profil hanya setelah pemicu terjadi, penyebab utama mungkin sudah hilang.
Misalnya, operasi yang berjalan lama di UI thread menyebabkan error Application Not Responding (ANR). Pada saat sistem mendeteksi ANR dan memberi sinyal pada aplikasi, operasi mungkin telah selesai. Memulai profil pada saat itu tidak akan memblokir pekerjaan yang sebenarnya.
Memprediksi secara tepat kapan beberapa pemicu terjadi tidak mungkin dilakukan, sehingga tidak mungkin memulai profil secara manual sebelumnya.
Mengapa menggunakan pengambilan berbasis pemicu?
Alasan utama penggunaan pemicu pembuatan profil adalah untuk merekam data untuk peristiwa yang tidak dapat diprediksi, yang membuat aplikasi tidak dapat memulai perekaman secara manual sebelum peristiwa ini terjadi. Pemicu pembuatan profil dapat digunakan untuk:
- Men-debug masalah performa: Mendiagnosis ANR, kebocoran memori, dan masalah stabilitas lainnya.
- Mengoptimalkan perjalanan penting pengguna: Menganalisis dan meningkatkan kualitas alur, misalnya, peluncuran aplikasi.
- Memahami perilaku pengguna: Dapatkan insight tentang peristiwa, misalnya, keluar dari aplikasi yang dimulai pengguna.
Menyiapkan pemicu
Kode berikut menunjukkan cara mendaftar untuk pemicu
TRIGGER_TYPE_APP_FULLY_DRAWN dan menerapkan pembatasan kecepatan padanya.
Kotlin
fun recordWithTrigger() { val profilingManager = applicationContext.getSystemService(ProfilingManager::class.java) val triggers = ArrayList<ProfilingTrigger>() val triggerBuilder = ProfilingTrigger.Builder(ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN) .setRateLimitingPeriodHours(1) triggers.add(triggerBuilder.build()) val mainExecutor: Executor = Executors.newSingleThreadExecutor() val resultCallback = Consumer<ProfilingResult> { profilingResult -> if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.resultFilePath ) setupProfileUploadWorker(profilingResult.resultFilePath) } else { Log.e( "ProfileTest", "Profiling failed errorcode=" + profilingResult.errorCode + " errormsg=" + profilingResult.errorMessage ) } } profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback) profilingManager.addProfilingTriggers(triggers)
Java
public void recordWithTrigger() { ProfilingManager profilingManager = getApplicationContext().getSystemService( ProfilingManager.class); List<ProfilingTrigger> triggers = new ArrayList<>(); ProfilingTrigger.Builder triggerBuilder = new ProfilingTrigger.Builder( ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN); triggerBuilder.setRateLimitingPeriodHours(1); triggers.add(triggerBuilder.build()); 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()); } } }; profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback); profilingManager.addProfilingTriggers(triggers);
Kode ini melakukan langkah-langkah berikut:
- Dapatkan pengelola: Mengambil layanan
ProfilingManager. - Menentukan pemicu: Membangun
ProfilingTriggeruntukTRIGGER_TYPE_APP_FULLY_DRAWN. Peristiwa ini terjadi saat aplikasi melaporkan bahwa aplikasi telah menyelesaikan proses startup dan bersifat interaktif. - Menetapkan batas frekuensi: Menerapkan batas frekuensi 1 jam ke pemicu tertentu ini
(
setRateLimitingPeriodHours(1)). Hal ini mencegah aplikasi merekam lebih dari satu profil peluncuran per jam. - Daftarkan pemroses: Memanggil
registerForAllProfilingResultsuntuk menentukan callback yang menangani hasil. Callback ini menerima jalur profil yang disimpan melaluigetResultFilePath(). - Tambahkan pemicu: Mendaftarkan daftar pemicu dengan
ProfilingManagermenggunakanaddProfilingTriggers. - Fire event: Memanggil
reportFullyDrawn(), yang memancarkan peristiwaTRIGGER_TYPE_APP_FULLY_DRAWNke sistem yang memicu pengumpulan profil dengan asumsi bahwa pelacakan latar belakang sistem sedang berjalan dan kuota pembatas laju tersedia. Langkah opsional ini menunjukkan alur end-to-end karena aplikasi Anda harus memanggilreportFullyDrawn()untuk pemicu ini.
Mengambil rekaman aktivitas
Sistem menyimpan profil berbasis pemicu di direktori yang sama dengan profil lainnya. Nama file untuk rekaman aktivitas yang dipicu mengikuti format ini:
profile_trigger_<profile_type_code>_<datetime>.<profile-type-name>
Anda dapat menarik file menggunakan ADB. Misalnya, untuk menarik rekaman aktivitas sistem yang diambil dengan kode contoh menggunakan ADB, perintahnya mungkin terlihat seperti ini:
adb pull /data/user/0/com.example.sampleapp/files/profiling/profile_trigger_1_2025-05-06-14-12-40.perfetto-trace
Untuk mengetahui detail tentang memvisualisasikan rekaman aktivitas ini, lihat Mengambil dan menganalisis data pembuatan profil.
Cara kerja penelusuran di latar belakang
Untuk merekam data dari sebelum pemicu, OS akan memulai rekaman aktivitas latar belakang secara berkala. Jika pemicu terjadi saat rekaman aktivitas latar belakang ini aktif dan aplikasi Anda terdaftar untuknya, sistem akan menyimpan profil rekaman aktivitas ke direktori aplikasi Anda. Profil kemudian akan menyertakan informasi yang menyebabkan pemicu.
Setelah profil disimpan, sistem akan memberi tahu aplikasi Anda menggunakan callback
yang diberikan ke registerForAllProfilingResults. Callback ini menyediakan jalur ke
profil yang direkam yang dapat diakses dengan memanggil
ProfilingResult#getResultFilePath().
Untuk mengurangi dampak pada performa perangkat dan daya tahan baterai, sistem tidak menjalankan rekaman aktivitas latar belakang secara terus-menerus. Sebagai gantinya, metode ini menggunakan metode pengambilan sampel. Sistem secara acak memulai rekaman aktivitas latar belakang dalam jangka waktu yang ditetapkan (dengan durasi minimum dan maksimum). Memberi jarak secara acak pada rekaman aktivitas ini akan meningkatkan cakupan pemicu.
Profil yang dipicu sistem memiliki ukuran maksimum yang ditentukan sistem, sehingga menggunakan buffer ring. Setelah buffer penuh, data rekaman aktivitas baru akan menggantikan data terlama. Seperti yang ditunjukkan pada Gambar 1, rekaman aktivitas yang diambil mungkin tidak mencakup seluruh durasi perekaman latar belakang jika buffer penuh; sebagai gantinya, rekaman aktivitas tersebut merepresentasikan aktivitas terbaru yang memicu perekaman.
Menerapkan pembatasan kapasitas khusus pemicu
Pemicu frekuensi tinggi dapat dengan cepat menghabiskan kuota pembatas kecepatan aplikasi Anda. Untuk lebih memahami pembatas kecepatan, sebaiknya Anda melihat Cara kerja pembatas kecepatan. Untuk mencegah satu jenis pemicu menghabiskan kuota Anda, Anda dapat menerapkan pembatasan kecepatan khusus pemicu.
ProfilingManager mendukung pembatasan kapasitas khusus pemicu yang ditentukan aplikasi. Hal ini memungkinkan Anda menambahkan lapisan lain pembatasan berbasis waktu selain pembatas kecepatan yang ada. Gunakan setRateLimitingPeriodHours API untuk menyetel waktu tunggu
tertentu untuk pemicu. Setelah periode tunggu berakhir, Anda dapat memicunya
lagi.
Men-debug pemicu secara lokal
Karena rekaman aktivitas latar belakang berjalan pada waktu acak, pemicuan proses debug secara lokal sulit dilakukan. Untuk memaksa rekaman aktivitas latar belakang untuk pengujian, gunakan perintah ADB berikut:
adb shell device_config put profiling_testing system_triggered_profiling.testing_package_name <com.example.myapp>
Perintah ini memaksa sistem untuk memulai rekaman aktivitas latar belakang berkelanjutan untuk paket yang ditentukan, sehingga setiap pemicu dapat mengumpulkan profil jika pembatas kecepatan mengizinkan.
Anda juga dapat mengaktifkan opsi debug lainnya, misalnya, menonaktifkan pembatas kecepatan saat melakukan proses debug secara lokal. Untuk mengetahui informasi selengkapnya, lihat Perintah debug untuk pembuatan profil lokal.