O ViewCapture é uma ferramenta de software que captura as propriedades das visualizações (como localização, tamanho, escala e visibilidade) anexadas às janelas em que está conectado. O ViewCapture captura informações sobre as várias visualizações em uma janela e as propriedades delas, informando o estado da experiência do usuário em momentos específicos e rastreando as mudanças ao longo do tempo.
As gravações de tela podem mostrar o estado de uma visualização em um momento específico e como ela muda, mas elas exigem recursos significativos da CPU e podem afetar o desempenho. A ferramenta ViewCapture tem menos impacto nos recursos e pode ser ativada com mais frequência. Além disso, o ViewCapture mostra visualizações quadro por quadro no nível da visualização, facilitando a inspeção do estado da visualização em momentos específicos em comparação com gravações de tela.
Esta página descreve como integrar o ViewCapture a apps do sistema.
Uso
ViewCapture.java
implementa uma instância de onDrawListener
e coleta um
traço de ViewCapture durante o processo de exibição. Cada quadro redesenhado aciona uma
translação da hierarquia da árvore de visualização, começando pela visualização raiz da janela.
O ViewCapture usa métodos de getter View.java
públicos para buscar e copiar valores para uma
linha de execução em segundo plano e melhorar o desempenho. A implementação da ViewCapture
otimiza esse processo verificando se uma visualização está suja ou invalidada usando captureViewTree
,
evitando a travessia de toda a hierarquia de visualizações. captureViewTree
está
disponível apenas para apps do sistema e faz parte da API UnsupportedAppUsage.
O uso dessa API é limitado a apps baseados na versão do SDK de destino.
Limitações
As seções a seguir descrevem as limitações de desempenho e memória na execução do ViewCapture.
Desempenho
A sobrecarga média da linha de execução principal para a performance do ViewCapture é
195 μs. No entanto, no pior cenário, pode levar
aproximadamente 5 ms. Consulte a fatia vc#onDraw
no
rastreamento do
Perfetto.
Os custos indiretos são principalmente devido às seguintes ações:
- A travessia da hierarquia custa 50 μs, mesmo quando podada.
- Extrair objetos de um alocador de lista livre para armazenar cópias de propriedades de visualização custa 20 μs.
- A busca de cada valor de propriedade por uma função getter resulta em muitas chamadas de função adicionais por visualização, custando 110 μs.
Portanto, ativar o ViewCapture no rastreamento sempre ativo (AOT, na sigla em inglês) afeta negativamente o desempenho do sistema e causa instabilidade. Devido a essas limitações de desempenho e memória, essa abordagem não está pronta para AOT. Recomendamos o ViewCapture apenas para laboratório e depuração local.
Memória
O método do Perfetto para rastros de ViewCapture usa um único buffer de anel, que tem um consumo de memória predefinido para evitar o uso excessivo de memória. Essa abordagem evita o consumo excessivo de memória evitando o uso de buffers de anel separados para cada janela, mas não resolve o problema de armazenar toda a hierarquia de visualização para cada estado no Perfetto para cada frame. A gravação de uma única janela, como NexusLauncher, pode produzir mais de 30 segundos de dados de ViewCapture em um buffer de 10 MB. No entanto, capturar mais de 30 janelas da IU do sistema exige um buffer maior ou uma janela de tempo de gravação consideravelmente menor.
Instruções
Siga estas instruções para integrar o ViewCapture a apps do sistema:
Adicione a dependência ao arquivo
Android.bp
, conforme mostrado no código do inicializador.android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }
Crie uma instância de ViewCapture ao criar a janela, por exemplo:
-
private SafeCloseable mViewCapture; @Override protected void onCreate(Bundle savedInstanceState) { ... mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow()); }
-
private SafeCloseable mViewCapture; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (enableViewCaptureTracing()) { mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext()) .startCapture(getRootView(), ".NotificationShadeWindowView"); } ... }
-
Feche a instância da ViewCapture ao destruir a janela, conforme mostrado nos exemplos abaixo: