Detecção de instabilidade da IU

O Android renderiza a IU gerando um frame do seu app e o mostrando na tela. Se o app tiver uma renderização lenta da IU, o sistema será forçado a ignorar frames. Quando isso acontece, o usuário percebe problemas recorrentes na tela, conhecidos como instabilidades.

Quando a instabilidade ocorre, geralmente ela está relacionada a alguma desaceleração ou bloqueio da chamada assíncrona na linha de execução de IU, que na maioria dos apps, é a linha de execução principal. Use os rastreamentos do sistema para identificar onde está o problema.

Detectar instabilidades no Android 12 e versões mais recentes

Para dispositivos que usam o Android 12 (API de nível 31) ou versões mais recentes, um rastro capturado é mostrado na faixa Janky frames no painel Display do CPU Profiler.

Para detectar instabilidades:

  1. No Android Studio, selecione View > Tool Windows > Profiler ou clique em Profile na barra de ferramentas.

    Se a caixa de diálogo Select Deployment Target solicitar, selecione o dispositivo em que o app vai ser implantado para criar o perfil. Se você estiver conectado a um dispositivo por USB, mas ele não for exibido na lista, verifique se a depuração USB está ativada.

  2. Clique em qualquer lugar da linha do tempo da CPU para abrir o CPU Profiler.

  3. Selecione System Trace no menu de configurações do CPU Profiler e clique em Record. Quando terminar de interagir com o app, clique em Stop.

  4. A faixa Janky frames aparece na guia Display. Por padrão, o CPU Profiler mostra apenas frames instáveis como candidatos para investigação. Em cada frame instável, a parte vermelha destaca a duração do frame que ultrapassa o prazo de renderização. Captura de tela da faixa Janky frames

  5. Quando encontrar um frame instável, clique nele. Você também pode pressionar M para ajustar o zoom e focar no frame selecionado. Os eventos relevantes são destacados nestas linhas de execução: a principal, RenderThread e GPU completion. Captura de tela do CPU Profiler mostrando frames instáveis e as linhas de execução principais

  6. Você também pode conferir todos os frames ou um detalhamento do tempo de renderização marcando as caixas de seleção All Frames e Lifecycle, respectivamente. Captura de tela do CPU Profiler, como mostrado acima, mas com as caixas de seleção "All Frames" e "Lifecycle" marcadas

Detectar instabilidade no Android 11

Para dispositivos que usam o Android 11 (API de nível 30), um rastro capturado é mostrado na seção Frame Lifecycle no CPU Profiler.

Seção "Frame Lifecycle" com faixas diferentes

A seção Frame Lifecycle contém o nome da camada e quatro faixas. Cada faixa representa uma fase no pipeline de renderização do frame. Os elementos da seção Frame Lifecycle são os seguintes:

  1. Frame Lifecycle (nome da camada): o título da seção contém o nome da camada entre parênteses. Uma camada é uma única unidade de composição.
  2. Application: esta faixa mostra o momento em que o buffer foi retirado da fila pelo app até o momento em que ele foi colocado de volta na fila. Isso geralmente corresponde aos eventos de traces na RenderThread.
  3. Wait for GPU: esta faixa mostra por quanto tempo o buffer pertenceu à GPU. Esse é o período entre o envio do buffer para a GPU e o momento em que a GPU terminou o trabalho no buffer. Isso não indica que a GPU estava funcionando apenas nesse buffer durante o período. Para ver informações detalhadas sobre o que a GPU faz durante um determinado período, use o Android GPU Inspector.
  4. Composition: esta faixa mostra o momento em que o SurfaceFlinger travou no buffer e o enviou para composição até o momento em que o buffer foi enviado à tela.
  5. Frames on display: esta faixa mostra por quanto tempo o frame ficou na tela.

A seção Frame Lifecycle ilustra como um buffer de frame se move entre diferentes fases do pipeline de renderização. Os frames são codificados por cor de acordo com o número de frames para facilitar o acompanhamento de um frame específico.

O Android Studio também mostra todos os frames no rastro em um formato de tabela na guia All Frames.

Uma tabela com todos os frames do rastro na guia "All Frames"

As colunas Frame #, Application, Wait for GPU e Composition representam os mesmos dados das faixas na seção Frame Lifecycle descritos acima. A coluna Frame Duration representa o tempo entre o início de Application e o início de Frames on Display. Esse é essencialmente o tempo necessário para renderizar um frame de ponta a ponta.

Você pode ordenar a tabela de frames por qualquer coluna para encontrar rapidamente o frame mais curto ou mais longo. A tabela também tem suporte a controles de paginação que ajudam você a navegar por centenas de frames.

Para detectar e investigar a instabilidade no Android 11, siga estas etapas:

  1. Classifique a tabela All Frames pela coluna Application em ordem decrescente para que os frames de maior duração apareçam primeiro.

    Coluna "Application" classificada em ordem decrescente

  2. Encontre os frames mais longos e selecione a linha da tabela. Isso aumenta o zoom no frame selecionado na visualização da linha do tempo à esquerda.

    Visualização da linha do tempo com a tabela "Frames"

  3. Procure linhas de execução relevantes nas seções Frame Lifecycle e Threads.

    Seções "Frame Lifecycle" e "Threads"

Detectar instabilidade no Android 10 e versões anteriores

Para dispositivos que usam o Android 10 (API de nível 29) e versões anteriores, as informações relevantes do pipeline de gráficos do SO são mostradas em uma única seção no rastreamento do sistema CPU Profiler, chamada Display.

A janela de exibição da IU

  • Frames: esta seção mostra a linha de execução de IU e os eventos de rastreamento RenderThread no app. Os eventos com mais de 16ms são mostrados em vermelho para destacar possíveis frames instáveis que excedem o prazo de renderização de 60 quadros por segundo (QPS).
  • SurfaceFlinger: esta seção mostra o momento de processamento dos buffers de frame pelo SurfaceFlinger. O SurfaceFlinger é um processo do sistema responsável por enviar buffers para exibição.
  • VSYNC: esta seção mostra o VSYNC, um sinal que sincroniza o pipeline de exibição. A faixa inclui o indicador VSYNC-app, que mostra quando o app está iniciando tarde demais. Normalmente, isso ocorre porque a linha de execução de IU está ocupada. Uma oscilação visível aparece na tela durante uma animação, adicionando mais latência de entrada até que a animação ou rolagem seja concluída. Isso é especialmente importante na visualização de telas com alta taxa de atualização, já que elas podem ocorrer com frequência maior que 60 vezes por segundo ou a uma taxa variável.
  • BufferQueue: esta seção mostra quantos buffers de frame estão na fila aguardando o consumo pelo SurfaceFlinger. Para apps implantados em dispositivos com o Android 9 (API de nível 28) ou versões mais recentes, essa faixa mostra a contagem de buffers da BufferQueue superficial do app (0, 1 ou 2). A BufferQueue pode ajudar a entender o estado dos buffers de imagem conforme eles são transferidos entre os componentes gráficos Android. Por exemplo, o valor 2 significa que o app está em buffer triplo no momento, podendo resultar em mais latência de entrada.

A seção Display oferece sinais úteis para detectar possíveis instabilidades. Por exemplo, quando a linha de execução de IU ou a RenderThread demora mais de 16ms. Para investigar detalhes exatos do que causou a instabilidade, você pode analisar a seção Threads, que mostra as linhas de execução relevantes para a renderização da IU.

Seção "Threads" em "Display"

Na imagem acima, a seção Threads mostra a linha de execução de IU (java.com.google.samples.apps.iosched), RenderThread e a linha de execução GPU completion. Essas são as linhas de execução relevantes para a renderização da IU e podem contribuir para a instabilidade.

Para detectar instabilidade no Android 10 e em versões anteriores, siga estas etapas:

  1. Observe a faixa Frames em Display. Os frames vermelhos são candidatos a investigação.

    Seção "Frames" em "Display"

  2. Quando você encontrar um frame possivelmente instável, aperte W ou role a roda do mouse com a tecla Ctrl (Command no macOS) pressionada para aumentar o zoom. Continue aumentando o zoom até começar a ver os eventos de traces na linha de execução de IU e na RenderThread.

    Eventos de rastreamento na linha de execução de IU e na RenderThread

    Na imagem acima, Choreographer#doFrame mostra quando a linha de execução de IU chama Choreographer para coordenar a animação, o layout de visualização, o desenho da imagem e os processos relacionados. DrawFrames mostra quando a RenderThread se forma e emite comandos de desenho reais para a GPU.

  3. Se você vir um evento de rastreamento particularmente longo, aumente o zoom e descubra o que pode ter contribuído para a renderização lenta. A imagem acima mostra o evento inflate na linha de execução de IU, o que significa que o app está gastando tempo para inflar o layout. Ao aumentar o zoom em um dos eventos inflate, é possível descobrir exatamente quanto tempo cada componente da IU está levando, conforme mostrado abaixo.

    Menu mostrando a duração exata de um componente de IU

Saiba mais

Para saber mais sobre como reduzir a instabilidade, consulte Fontes comuns de instabilidade.