tipos - verbose android studio




Significado das mensagens do coreógrafo no Logcat (4)

Esta é uma mensagem de informação que pode aparecer em seu LogCat em muitas situações.

No meu caso, aconteceu quando eu estava inflar diversas visualizações de arquivos de layout XML programaticamente. A mensagem é inofensiva por si só, mas poderia ser o sinal de um problema posterior que usaria toda a memória RAM que seu App pode usar e fará com que o Mega-mal Force Close aconteça. Eu cresci para ser o tipo de desenvolvedor que gosta de ver seu Log WARN / INFO / ERROR Free. ;)

Então, esta é a minha própria experiência:

Recebi a mensagem:

10-09 01:25:08.373: I/Choreographer(11134): Skipped XXX frames!  The application may be doing too much work on its main thread.

... quando eu criava minha própria "lista de super-seções super-complexas" inflando uma visão de XML e preenchendo seus campos (imagens, texto, etc ...) com os dados vindos da resposta de um REST / Serviço web JSON (sem recursos de paginação), essa visão atuaria como linhas, cabeçalhos de subseções e cabeçalhos de seção, adicionando todos eles na ordem correta a um LinearLayout (com orientação vertical dentro de um ScrollView). Tudo isso para simular um listView com elementos clicáveis ​​... mas bem, isso é para outra pergunta.

Como desenvolvedor responsável, você quer tornar o App realmente eficiente com os recursos do sistema, portanto, a melhor prática para listas (quando suas listas não são tão complexas) é usar um ListActivity ou ListFragment com um Loader e preencher o ListView com um adaptador, isso é supostamente mais eficiente, na verdade é e você deve fazer isso o tempo todo, de novo ... se a sua lista não for tão complexa.

Solução: eu implementei paginação em meu serviço da Web REST / JSON para evitar "grandes tamanhos de resposta" e agrupei o código que adicionou as visualizações "rows", "section headers" e "sub-section headers" em um AsyncTask para manter o Main Thread legal.

Então ... espero que minha experiência ajude alguém que está abrindo suas cabeças com esta mensagem de informação.

Hacker feliz!

Esta questão já tem uma resposta aqui:

Eu instalei as versões mais recentes do SDK (API 16) e recebi o ADT mais recente. Agora estou vendo essas mensagens no logcat, que tenho certeza, não vi antes. Alguém tem uma ideia sobre isso?

06-29 23: 11: 17.796: I / Coreógrafo (691): pulou 647 quadros! O aplicativo pode estar fazendo muito trabalho em seu thread principal.

Eu fiz uma pesquisa e encontrei este link: http://developer.android.com/reference/android/view/Choreographer.html . Esta é uma nova classe introduzida na API 16.

Eu preciso saber como eu posso determinar o que "muito trabalho" meu aplicativo pode estar fazendo como todo o meu processamento é feito em AsyncTask s.


Estou atrasado para a festa, mas espero que este seja um complemento útil para as outras respostas aqui ...

Respondendo a pergunta / tl: dr;

Eu preciso saber como eu posso determinar o que "muito trabalho" meu aplicativo pode estar fazendo como todo o meu processamento é feito em AsyncTasks.

A seguir estão todos os candidatos:

  • IO ou processamento caro no thread principal (carregar drawables, inflar layouts e configurar Uri em ImageView , todos constituem IO no thread principal)
  • Renderização de hierarquias grandes / complexas / profundas
  • Invalidando grandes partes de uma hierarquia de View
  • Métodos onDraw caros em View personalizadas
  • Cálculos caros em animações
  • Executando threads "worker" com uma prioridade muito alta para ser considerado "background" ( AsyncTask são "background" por padrão, java.lang.Thread não é)
  • Gerando muito lixo, fazendo com que o coletor de lixo "pare o mundo" - incluindo o segmento principal - enquanto ele limpa

Para determinar a causa específica, você precisará criar um perfil para seu aplicativo.

Mais detalhes

Eu tenho tentado entender o Coreógrafo experimentando e olhando o code .

A documentação do Coreógrafo é aberta com "Coordena o tempo de animações, entrada e desenho". o que é realmente uma boa descrição, mas o resto continua enfatizando as animações.

O Coreógrafo é na verdade responsável pela execução de 3 tipos de retorno de chamada, que são executados nesta ordem:

  1. callbacks de manipulação de entrada (manipulação de entradas do usuário, como eventos de toque)
  2. callbacks de animação para interpolação entre quadros, fornecendo um tempo de início de quadro estável para qualquer / todas as animações em execução. Executar estes callbacks 2nd significa que quaisquer cálculos relacionados a animação (por exemplo, alterar posições de View) já foram feitos no momento em que o terceiro tipo de retorno de chamada é invocado ...
  3. visualizar retornos de chamada de percurso para desenhar a hierarquia da vista.

O objetivo é combinar a taxa em que as visualizações invalidadas são redesenhadas (e as animações interpoladas) com a tela vsync - normalmente 60fps.

O aviso sobre quadros ignorados parece uma reflexão tardia: A mensagem é registrada se uma única passagem pelas três etapas levar mais de 30x a duração esperada do quadro, portanto, o menor número que você pode esperar nas mensagens de log é "ignorado 30 quadros" ; Se cada passe demorar 50% a mais do que deveria, você ainda poderá pular 30 quadros ( desobediente! ), Mas você não será avisado sobre isso.

Dos três passos envolvidos está claro que não são apenas as animações que podem acionar o aviso: a invalidação de uma porção significativa de uma grande hierarquia View ou uma View com um complicado método onDraw pode ser suficiente.

Por exemplo, isso acionará o aviso repetidamente:

public class AnnoyTheChoreographerActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.simple_linear_layout);

        ViewGroup root = (ViewGroup) findViewById(R.id.root);

        root.addView(new TextView(this){
            @Override
            protected void onDraw(Canvas canvas) {
                super.onDraw(canvas);
                long sleep = (long)(Math.random() * 1000L);
                setText("" + sleep);
                try {
                    Thread.sleep(sleep);
                } catch (Exception exc) {}
            }
        });
    }
}

... o que produz logging assim:

11-06 09:35:15.865  13721-13721/example I/Choreographer Skipped 42 frames!  The application may be doing too much work on its main thread.
11-06 09:35:17.395  13721-13721/example I/Choreographer Skipped 59 frames!  The application may be doing too much work on its main thread.
11-06 09:35:18.030  13721-13721/example I/Choreographer Skipped 37 frames!  The application may be doing too much work on its main thread.

Você pode ver na pilha durante o onDraw que o coreógrafo está envolvido, independentemente de você estar animando:

em example.AnnoyTheChoreographerActivity $ 1.onDraw (AnnoyTheChoreographerActivity.java:25) em android.view.View.draw (View.java:13759)

... um pouco de repetição ...

em android.view.ViewGroup.drawChild (ViewGroup.java:3169) em android.view.ViewGroup.dispatchDraw (ViewGroup.java:3039) em android.view.View.draw (View.java:13762) em android.widget. FrameLayout.draw (FrameLayout.java:467) em com.android.internal.policy.impl.PhoneWindow $ DecorView.draw (PhoneWindow.java:2396) em android.view.View.getDisplayList (View.java:12710) em android .view.View.getDisplayList (View.java:12754) em android.view.HardwareRenderer $ GlRenderer.draw (HardwareRenderer.java:1144) em android.view.ViewRootImpl.draw (ViewRootImpl.java:2273) em android.view. ViewRootImpl.performDraw (ViewRootImpl.java:2145) em android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1956) em android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1112) em android.view.ViewRootImpl $ TraversalRunnable.run (ViewRootImpl.java:4472) em android.view.Choreographer $ CallbackRecord.run (Choreographer.java:725) em android.view.Choreographer.doCallbacks (Choreographer.java:555) em android.view.Choreographer.doFrame (Cho reographer.java:525) em android.view.Choreographer $ FrameDisplayEventReceiver.run (Choreographer.java:711) em android.os.Handler.handleCallback (Handler.java:615) em android.os.Handler.dispatchMessage (Handler.java : 92) em android.os.Looper.loop (Looper.java:137) em android.app.ActivityThread.main (ActivityThread.java:4898)

Por fim, se houver contenção de outros encadeamentos que reduzam a quantidade de trabalho que o encadeamento principal pode obter, a chance de ignorar quadros aumenta drasticamente, embora você não esteja realmente fazendo o trabalho no encadeamento principal.

Nessa situação, pode ser considerado enganoso sugerir que o aplicativo está fazendo muito no thread principal, mas o Android realmente quer que os threads de trabalho sejam executados com baixa prioridade, para que eles sejam impedidos de privar o thread principal. Se seus threads de trabalho tiverem baixa prioridade, a única maneira de acionar o aviso do Choreographer é fazer muito no thread principal.


No meu caso eu tenho essas mensagens quando mostro a barra de ação do sherlock inderterminar a barra de progresso. Como não é minha biblioteca, decidi esconder as saídas do Coreógrafo.

Você pode ocultar as saídas do Coreógrafo na visualização Logcat, usando esta expressão de filtro:

tag: ^ ((?! Coreógrafo). *) $

Eu usei um regex explicado em outro lugar: expressão regular para combinar com uma linha que não contém uma palavra?


O Coreógrafo permite que os aplicativos se conectem ao vsync e, adequadamente, consumam tempo para melhorar o desempenho.

As animações de visualização do Android usam internamente o Choreographer para o mesmo propósito: dar um tempo adequado às animações e, possivelmente, melhorar o desempenho.

Como o Choreographer é informado sobre todos os eventos vsync, posso dizer se uma das Runnables transmitidas pelo Choreographer.post * apis não termina no tempo de um frame, fazendo com que os frames sejam pulados.

No meu entender, o coreógrafo só consegue detectar o quadro pulando. Não tem como dizer por que isso acontece.

A mensagem "O aplicativo pode estar fazendo muito trabalho em seu segmento principal". poderia ser enganador.





android-logcat