Seguimiento nativo

En esta guía, se describe cómo usar la API nativa de seguimiento (trace.h) para escribir los eventos de seguimiento en el búfer del sistema. A continuación, puedes analizar los resultados del seguimiento mediante la herramienta Systrace. La API nativa de seguimiento es compatible con los niveles de Android API 23 y superiores.

Descripción general

La creación de un seguimiento personalizado en código nativo es similar a la técnica para el lenguaje de programación de Java, que se describe en Seguimiento del código de la aplicación. En general, no necesitas colocar el código de seguimiento nativo en bloques try/catch a menos que la sección en la que se hizo el seguimiento arroje una excepción nativa o use un valor de retorno anterior.

Para cada llamada ATrace_beginSection() , asegúrate también de tener una llamada ATrace_endSection() correspondiente; de lo contrario, podría dañarse un archivo de seguimiento.

Para evitar compilar cadenas o argumentos complejos cuando el seguimiento no está habilitado, puedes agregar una protección si llamas a ATrace_isEnabled() .

Seguimiento de una función

Un caso de uso para la API nativa de seguimiento es observar el tiempo que se toma un bloque de código en particular. En general, este seguimiento se hace durante la etapa de procesamiento de flujos (por ejemplo, cuando se decodifica una imagen, se dibuja un marco o se espera una solicitud de red).

Para hacer un seguimiento del tiempo que se toma un bloque de código, sigue estos pasos:

  1. Incluye el archivo de encabezado trace.h .
    #include <android/trace.h>
    
  2. Especifica una variable como nombre de la sección en ATrace_beginSection(). Al final del bloque de código para el cual quieras hacer un seguimiento, haz la llamada correspondiente a ATrace_endSection(). Esto es importante sobre todo cuando la sección en la cual se hizo el seguimiento arroja una excepción nativa o usa un valor de retorno anterior.
    void myExpensiveFunction() {
      ATrace_beginSection("myExpensiveFunction");
      ... // trace-worthy work here
      ATrace_endSection();
    }
    
  3. (Opcional) Crea una estructura de objetos/macros conveniente para hacer un seguimiento de los bloques de código. En el ejemplo siguiente, se muestra cómo implementar este objeto/macro denominado ATRACE_CALL().
    #define ATRACE_NAME(name) ScopedTrace ___tracer(name)
    
    // ATRACE_CALL is an ATRACE_NAME that uses the current function name.
    #define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
    
    class ScopedTrace {
      public:
        inline ScopedTrace(const char *name) {
          ATrace_beginSection(name);
        }
    
        inline ~ScopedTrace() {
          ATrace_endSection();
        }
    };
    
    Al usar el objeto/macro ATRACE_CALL(), puedes simplificar el código desde el paso anterior como se muestra a continuación. Cuando usas el objeto/macro de esta manera, no necesitas preocuparte por agregar bloques try/catch cuando la sección en la que se realizó el seguimiento arroja una excepción o usa un valor de retorno anterior.
    void myExpensiveFunction() {
      ATRACE_CALL();
      ... // trace-worthy work here
    }