ViewCapture es una herramienta de software que captura las propiedades de las vistas (como la ubicación, el tamaño, la escala y la visibilidad) adjuntas a las ventanas a las que está conectada. ViewCapture captura información sobre las diversas vistas dentro de una ventana y sus propiedades, lo que te permite conocer el estado de la experiencia del usuario en momentos específicos y hacer un seguimiento de los cambios a lo largo del tiempo.
Las grabaciones de pantalla pueden visualizar el estado de una vista en un momento específico y mostrar cómo cambia, pero requieren recursos significativos de CPU y pueden afectar el rendimiento. La herramienta ViewCapture tiene un menor impacto en los recursos y se puede habilitar con mayor frecuencia. Además, ViewCapture muestra visualizaciones fotograma por fotograma a nivel de la vista, lo que facilita la inspección del estado de la vista en momentos específicos en comparación con las grabaciones de pantalla.
En esta página, se describe cómo incorporar ViewCapture en las apps del sistema.
Usar
ViewCapture.java implementa una instancia de onDrawListener y recopila un seguimiento de ViewCapture durante el proceso de dibujo. Cada redibujo de fotograma activa un recorrido por la jerarquía del árbol de vistas que comienza en la vista raíz de la ventana.
ViewCapture usa métodos de obtención View.java
públicos para recuperar y copiar valores en un
subproceso en segundo plano para mejorar el rendimiento. La implementación de ViewCapture
optimiza este proceso verificando si una vista está sucia o invalidada con captureViewTree,
lo que evita el recorrido de toda la jerarquía de vistas. captureViewTree solo está disponible para las apps del sistema y forma parte de la API de UnsupportedAppUsage.
El uso de esta API se limita a las apps según su versión de SDK objetivo.
Limitaciones
En esta sección, se describen las limitaciones de rendimiento y memoria de ViewCapture.
Rendimiento
La sobrecarga promedio del subproceso principal para el rendimiento de ViewCapture es de 195 μs. Sin embargo, en el peor de los casos, puede tardar
aproximadamente 5 ms. Consulta el segmento vc#onDraw en el
seguimiento
de Perfetto.
Los costos de sobrecarga se deben principalmente a las siguientes acciones:
- Recorrer la jerarquía cuesta 50 μs, incluso cuando se poda.
- Extraer objetos de un asignador de listas libres para almacenar copias de las propiedades de la vista cuesta 20 μs.
- Recuperar cada valor de propiedad a través de una función de obtención genera muchas llamadas de función adicionales por vista, lo que cuesta 110 μs.
Por lo tanto, habilitar ViewCapture en el seguimiento siempre activo (AOT) afecta negativamente el rendimiento del sistema y genera jank. Debido a estas limitaciones de rendimiento y memoria, este enfoque no está listo para AOT. Recomendamos ViewCapture solo para la depuración local y de laboratorio.
Memoria
El método de Perfetto para los seguimientos de ViewCapture usa un solo búfer de anillo con un espacio en memoria predefinido para evitar el uso excesivo de memoria. Este enfoque evita el consumo excesivo de memoria, ya que evita los búferes de anillo separados para cada ventana. Sin embargo, no resuelve el problema de almacenar toda la jerarquía de vistas para cada estado en Perfetto para cada fotograma. Grabar una sola ventana, como NexusLauncher, puede producir más de 30 segundos de datos de ViewCapture en un búfer de 10 MB. Para capturar más de 30 ventanas de la IU del sistema, se requiere un búfer más grande o un tiempo de grabación considerablemente más corto.
Instrucciones
Para incorporar ViewCapture en las apps del sistema, sigue estas instrucciones:
Agrega la dependencia a tu
Android.bparchivo, como se muestra en el código de Launcher.android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }Crea una instancia de ViewCapture cuando crees tu ventana, por ejemplo:
-
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"); } ... }
-
Cierra la instancia de ViewCapture cuando destruyas la ventana, como se muestra en los siguientes ejemplos: