Como capturar um perfil

Nesta página, mostramos como gravar um rastreamento do sistema usando a API ProfilingManager.

Adicionar dependências

Para ter a melhor experiência com a API ProfilingManager, adicione as seguintes bibliotecas do Jetpack ao arquivo 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'
   }
   

Registrar um rastro do sistema

Depois de adicionar as dependências necessárias, use o código a seguir para registrar um rastro do sistema. Este exemplo mostra uma configuração básica em um Activity para iniciar e gerenciar uma sessão de criação de perfil.

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();
}

O exemplo de código configura e gerencia a sessão de criação de perfil seguindo estas etapas:

  1. Configure o executor. Crie um Executor para definir a linha de execução que vai receber os resultados do perfil. A criação de perfil acontece em segundo plano. Usar um executor de linha de execução não relacionada à UI ajuda a evitar erros de "O app não está respondendo" (ANR) se você adicionar mais processamento ao callback depois.

  2. Processar resultados de criação de perfil. Crie um objeto Consumer<ProfilingResult>. O sistema usa esse objeto para enviar resultados de criação de perfil de ProfilingManager de volta ao seu app.

  3. Crie a solicitação de criação de perfil. Crie um SystemTraceRequestBuilder para configurar sua sessão de criação de perfil. Com esse builder, é possível personalizar as configurações de rastreamento do ProfilingManager. A personalização do builder é opcional. Se você não fizer isso, o sistema usará as configurações padrão.

    • Defina uma tag. Use setTag() para adicionar uma tag ao nome do rastreamento. Essa tag ajuda a identificar o rastreamento.
    • Opcional: defina a duração. Use setDurationMs() para especificar por quanto tempo fazer o perfil em milissegundos. Por exemplo, 60000 define um rastreamento de 60 segundos. O rastreamento termina automaticamente após a duração especificada se CancellationSignal não for acionado antes disso.
    • Escolha uma política de buffer. Use setBufferFillPolicy() para definir como os dados de rastreamento são armazenados. BufferFillPolicy.RING_BUFFER significa que, quando o buffer está cheio, os novos dados substituem os mais antigos, mantendo um registro contínuo da atividade recente.
    • Defina um tamanho de buffer. Use setBufferSizeKb() para especificar um tamanho de buffer para rastreamento, que pode ser usado para controlar o tamanho do arquivo de rastreamento de saída.
  4. Opcional: gerencie o ciclo de vida da sessão. Crie um CancellationSignal. Com esse objeto, você pode interromper a sessão de criação de perfil quando quiser, tendo controle preciso sobre a duração dela.

  5. Comece e receba resultados. Quando você chama requestProfiling(), ProfilingManager inicia uma sessão de criação de perfil em segundo plano. Depois que o criação de perfil é concluída, ela envia o ProfilingResult para seu método resultCallback#accept. Se o perfil for concluído com êxito, o ProfilingResult vai fornecer o caminho em que o rastreamento foi salvo no dispositivo pelo ProfilingResult#getResultFilePath. Você pode receber esse arquivo de forma programática ou, para criação de perfil local, executando adb pull <trace_path> no computador.

  6. Adicione pontos de trace personalizados. É possível adicionar pontos de trace personalizados no código do app. No exemplo de código anterior, uma fração de rastreamento chamada MyApp:HeavyOperation é adicionada usando Trace.beginSection() e Trace.endSection(). Essa seção personalizada aparece no perfil gerado, destacando operações específicas no app.