Rastreamento nativo

Este guia descreve como usar a API de rastreamento nativo (trace.h) para registrar eventos de rastreamento no buffer do sistema. Desse modo, você poderá analisar essa saída de rastreamento usando a ferramenta Systrace. A API de rastreamento nativo é compatível com os níveis de API 23 e superiores do Android.

Visão geral

O processo de criação de um rastreamento personalizado no código nativo é semelhante à técnica da linguagem de programação Java, descrita em Rastrear o código do aplicativo. Normalmente, não é necessário colocar seu código de rastreamento nativo em blocos try/catch, a menos que a seção rastreada gere uma exceção nativa ou use um retorno antecipado.

Cada chamada a ATrace_beginSection() precisa ter uma chamada a ATrace_endSection() correspondente. Caso contrário, ela poderá resultar em um arquivo de rastreamento corrompido.

Para evitar a compilação de argumentos ou strings complexas quando o rastreamento não estiver ativado, chame ATrace_isEnabled() para adicionar uma proteção .

Rastreamento de funções

Um caso de uso da API de rastreamento nativo é usá-la para observar o tempo gasto por um bloco de código. Normalmente, esse rastreamento ocorre durante o estágio de processamento do canal (por exemplo, ao decodificar uma imagem, desenhar um frame ou aguardar uma solicitação de rede).

Para rastrear o tempo gasto por um bloco de código, siga estas etapas:

  1. Inclua o arquivo de cabeçalho trace.h .
    #include <android/trace.h>
    
  2. Especifique uma variável como o nome da seção em ATrace_beginSection(). No final do bloco de código que você quer rastrear, faça uma chamada correspondente para ATrace_endSection(). Isso é importante principalmente quando a seção rastreada gera uma exceção nativa ou usa um retorno antecipado.
    void myExpensiveFunction() {
      ATrace_beginSection("myExpensiveFunction");
      ... // trace-worthy work here
      ATrace_endSection();
    }
    
  3. (Opcional) Crie uma estrutura de macro/objeto de conveniência para rastrear blocos de código. O exemplo a seguir mostra como implementar um objeto/macro desse tipo chamado 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();
        }
    };
    
    Com o objeto/macro ATRACE_CALL(), é possível simplificar o código da etapa anterior . Dessa forma, não é necessário adicionar blocos try/catch quando a seção rastreada gera uma exceção ou usa um retorno antecipado.
    void myExpensiveFunction() {
      ATRACE_CALL();
      ... // trace-worthy work here
    }