Come acquisire un profilo

Questa pagina mostra come registrare una traccia di sistema utilizzando l'API ProfilingManager.

Aggiungere dipendenze

Per un'esperienza ottimale con l'API ProfilingManager, aggiungi le seguenti librerie Jetpack al file build.gradle.kts.

Kotlin

   dependencies {
       implementation("androidx.tracing:tracing:1.3.0")
       implementation("androidx.core:core:1.16.0")
   }
   

Groovy

   dependencies {
       implementation 'androidx.tracing:tracing:1.3.0'
       implementation 'androidx.core:core:1.16.0'
   }
   

Registrare una traccia di sistema

Dopo aver aggiunto le dipendenze richieste, utilizza il seguente codice per registrare una traccia di sistema. Questo esempio mostra una configurazione di base all'interno di un Activity per avviare e gestire una sessione di profilazione.

Kotlin

@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
fun sampleRecordSystemTrace() {
    val mainExecutor: Executor =
        Dispatchers.IO.asExecutor() // Your choice of executor for the callback to occur on.
    val resultCallback = 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
            )
        }
    }
    val stopSignal = CancellationSignal()

    val requestBuilder = SystemTraceRequestBuilder()
    requestBuilder.setCancellationSignal(stopSignal)
    requestBuilder.setTag("FOO") // Caller supplied tag for identification
    requestBuilder.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 profile
    stopSignal.cancel()
}

fun heavyOperation() {
    // Computations you want 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());
          } 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(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 profile
  stopSignal.cancel();
}

Il codice di esempio configura e gestisce la sessione di profilazione seguendo i seguenti passaggi:

  1. Configura l'executor. Crea un Executor per definire il thread che riceverà i risultati della profilazione. La profilazione avviene in background. L'utilizzo di un executor di thread non UI consente di evitare errori ANR (L'applicazione non risponde) se in un secondo momento aggiungi ulteriore elaborazione al callback.

  2. Gestisci i risultati della profilazione. Crea un oggetto Consumer<ProfilingResult>. Il sistema utilizza questo oggetto per inviare i risultati della profilazione da ProfilingManager alla tua app.

  3. Crea la richiesta di profilazione. Crea un SystemTraceRequestBuilder per impostare la sessione di profilazione. Questo generatore ti consente di personalizzare le impostazioni di traccia ProfilingManager. La personalizzazione del builder è facoltativa; se non lo fai, il sistema utilizza le impostazioni predefinite.

    • Definisci un tag. Usa setTag() per aggiungere un tag al nome della traccia. Questo tag ti aiuta a identificare la traccia.
    • (Facoltativo) Imposta la durata. Utilizza setDurationMs() per specificare la durata del profilo in millisecondi. Ad esempio, 60000 imposta una traccia di 60 secondi. La traccia termina automaticamente dopo la durata specificata se CancellationSignal non viene attivato prima.
    • Scegli una policy del buffer. Utilizza setBufferFillPolicy() per definire la modalità di archiviazione dei dati di traccia. BufferFillPolicy.RING_BUFFER significa che quando il buffer è pieno, i nuovi dati sovrascrivono i dati meno recenti, mantenendo una registrazione continua dell'attività recente.
    • Imposta una dimensione del buffer. Utilizza setBufferSizeKb() per specificare una dimensione del buffer per la traccia, che puoi utilizzare per controllare le dimensioni del file di traccia di output.
  4. (Facoltativo) Gestisci il ciclo di vita della sessione. Crea un CancellationSignal. Questo oggetto ti consente di interrompere la sessione di profilazione in qualsiasi momento, offrendoti un controllo preciso sulla sua durata.

  5. Avvia e ricevi i risultati. Quando chiami requestProfiling(), ProfilingManager avvia una sessione di profilazione in background. Una volta completata la profilazione, invia ProfilingResult al tuo metodo di resultCallback#accept. Se la profilazione viene completata correttamente, ProfilingResult fornisce il percorso in cui la traccia è stata salvata sul dispositivo tramite ProfilingResult#getResultFilePath. Puoi ottenere questo file in modo programmatico o, per la profilazione locale, eseguendo adb pull <trace_path> dal tuo computer.

  6. Aggiungi punti di tracciamento personalizzati. Puoi aggiungere punti di tracciamento personalizzati nel codice della tua app. Nell'esempio di codice precedente, viene aggiunta una sezione di traccia denominata MyApp:HeavyOperation utilizzando Trace.beginSection() e Trace.endSection(). Questa sezione personalizzata viene visualizzata nel profilo generato, evidenziando operazioni specifiche all'interno dell'app.