Cómo capturar un perfil

En esta página, se muestra cómo registrar un registro del sistema con la API de ProfilingManager.

Cómo agregar dependencias

Para obtener la mejor experiencia con la API de ProfilingManager, agrega las siguientes bibliotecas de Jetpack a tu archivo 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'
   }
   

Cómo registrar un seguimiento del sistema

Después de agregar las dependencias requeridas, usa el siguiente código para registrar un seguimiento del sistema. En este ejemplo, se muestra una configuración básica dentro de un Activity para iniciar y administrar una sesión de generación de perfiles.

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

El código de muestra configura y administra la sesión de generación de perfiles siguiendo estos pasos:

  1. Configura el ejecutor. Crea un objeto Executor para definir el subproceso que recibirá los resultados de la generación de perfiles. La creación de perfiles se realiza en segundo plano. Usar un ejecutor de subprocesos que no sean de IU ayuda a evitar errores de aplicación no responde (ANR) si agregas más procesamiento a la devolución de llamada más adelante.

  2. Controla los resultados de la generación de perfiles. Crea un objeto Consumer<ProfilingResult>. El sistema usa este objeto para enviar los resultados de la creación de perfiles desde ProfilingManager a tu app.

  3. Crea la solicitud de generación de perfiles. Crea un SystemTraceRequestBuilder para configurar tu sesión de perfilado. Este compilador te permite personalizar la configuración de seguimiento de ProfilingManager. Personalizar el compilador es opcional. Si no lo haces, el sistema usará la configuración predeterminada.

    • Define una etiqueta. Usa setTag() para agregar una etiqueta al nombre del registro. Esta etiqueta te ayuda a identificar el registro.
    • Opcional: Establece la duración. Usa setDurationMs() para especificar cuánto tiempo se debe generar el perfil en milisegundos. Por ejemplo, 60000 establece un registro de 60 segundos. El registro finaliza automáticamente después de la duración especificada si CancellationSignal no se activa antes de eso.
    • Elige una política de búfer. Usa setBufferFillPolicy() para definir cómo se almacenan los datos de seguimiento. BufferFillPolicy.RING_BUFFER significa que, cuando el búfer está lleno, los datos nuevos reemplazan a los más antiguos, lo que mantiene un registro continuo de la actividad reciente.
    • Establece un tamaño de búfer. Usa setBufferSizeKb() para especificar un tamaño de búfer para el registro de seguimiento que puedes usar para controlar el tamaño del archivo de registro de seguimiento de salida.
  4. Opcional: Administra el ciclo de vida de la sesión. Crea un CancellationSignal. Este objeto te permite detener la sesión de generación de perfiles cuando quieras, lo que te brinda un control preciso sobre su duración.

  5. Comienza y recibe resultados. Cuando llamas a requestProfiling(), ProfilingManager inicia una sesión de generación de perfiles en segundo plano. Una vez que se completa la generación de perfiles, envía el ProfilingResult a tu método resultCallback#accept. Si la generación de perfiles finaliza correctamente, ProfilingResult proporciona la ruta de acceso en la que se guardó el registro en tu dispositivo a través de ProfilingResult#getResultFilePath. Puedes obtener este archivo de forma programática o, para la generación de perfiles local, ejecutando adb pull <trace_path> desde tu computadora.

  6. Agrega puntos de seguimiento personalizados. Puedes agregar puntos de seguimiento personalizados en el código de tu app. En el ejemplo de código anterior, se agrega un segmento de registro llamado MyApp:HeavyOperation con Trace.beginSection() y Trace.endSection(). Este segmento personalizado aparece en el perfil generado y destaca operaciones específicas dentro de tu app.