ViewCapture — это программный инструмент, который фиксирует свойства представлений (таких как местоположение, размер, масштаб и видимость), прикрепленных к окнам, к которым он подключен. ViewCapture собирает информацию о различных представлениях в окне и их свойствах, позволяя узнать состояние взаимодействия с пользователем в определенные моменты времени и отслеживать изменения с течением времени.
Записи экрана могут визуализировать состояние представления в определенное время и показать, как оно меняется, но они требуют значительных ресурсов ЦП и могут повлиять на производительность. Инструмент ViewCapture меньше потребляет ресурсы и его можно включать чаще. Кроме того, ViewCapture отображает визуализации кадр за кадром на уровне просмотра, что упрощает проверку состояния просмотра в определенные моменты по сравнению с записями экрана.
На этой странице описано, как подключить ViewCapture к системным приложениям.
Использовать
ViewCapture.java
реализует экземпляр onDrawListener
и собирает трассировку ViewCapture во время процесса рисования. Каждая перерисовка кадра запускает обход иерархии дерева представлений, начиная с корневого представления окна. ViewCapture использует общедоступные методы получения View.java
для извлечения и копирования значений в фоновый поток для повышения производительности. Реализация ViewCapture оптимизирует этот процесс, проверяя, является ли представление «грязным» или недействительным, с помощью captureViewTree
, что позволяет избежать обхода всей иерархии представлений. captureViewTree
доступен только для системных приложений и является частью UnsupportedAppUsage API. Использование этого API ограничено приложениями, основанными на их целевой версии SDK.
Ограничения
В следующих разделах описаны ограничения производительности и памяти при запуске ViewCapture.
Производительность
Средняя задержка основного потока для производительности ViewCapture составляет 195 мкс. Однако в худшем случае это может занять около 5 мс. Обратитесь к срезу vc#onDraw
в трассировке Perfetto .
Накладные расходы в основном обусловлены следующими действиями:
- Обход иерархии занимает 50 мкс, даже при обрезке.
- Извлечение объектов из распределителя свободного списка для хранения копий свойств представления стоит 20 мкс.
- Получение каждого значения свойства с помощью функции получения приводит к множеству дополнительных вызовов функций для каждого представления, что занимает 110 мкс.
Следовательно, включение ViewCapture в режиме постоянной трассировки (AOT) отрицательно влияет на производительность системы и приводит к зависаниям. Из-за ограничений производительности и памяти этот подход не готов к AOT. Мы рекомендуем ViewCapture только для лабораторной и локальной отладки.
Память
Метод Perfetto для трассировок ViewCapture использует один кольцевой буфер, который имеет предопределенный объем памяти для предотвращения чрезмерного использования памяти. Этот подход предотвращает чрезмерное потребление памяти, избегая использования отдельных кольцевых буферов для каждого окна, но не решает проблему хранения всей иерархии представлений для каждого состояния в Perfetto для каждого кадра. Запись одного окна, например NexusLauncher, может создать более 30 секунд данных ViewCapture в буфере размером 10 МБ. Однако захват более 30 окон из системного пользовательского интерфейса требует либо большего буфера, либо значительно более короткого окна времени записи.
Инструкции
Следуйте этим инструкциям, чтобы включить ViewCapture в системные приложения:
Добавьте зависимость в файл
Android.bp
, как показано в коде запуска .android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }
Создайте экземпляр ViewCapture при создании окна, например:
Пример 1 :
private SafeCloseable mViewCapture; @Override protected void onCreate(Bundle savedInstanceState) { ... mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow()); }
Пример 2 :
private SafeCloseable mViewCapture; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (enableViewCaptureTracing()) { mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext()) .startCapture(getRootView(), ".NotificationShadeWindowView"); } ... }
Закройте экземпляр ViewCapture при уничтожении окна, как показано в следующих примерах:
ViewCapture — это программный инструмент, который фиксирует свойства представлений (таких как местоположение, размер, масштаб и видимость), прикрепленных к окнам, к которым он подключен. ViewCapture собирает информацию о различных представлениях в окне и их свойствах, позволяя узнать состояние взаимодействия с пользователем в определенные моменты времени и отслеживать изменения с течением времени.
Записи экрана могут визуализировать состояние представления в определенное время и показать, как оно меняется, но они требуют значительных ресурсов ЦП и могут повлиять на производительность. Инструмент ViewCapture меньше потребляет ресурсы и его можно включать чаще. Кроме того, ViewCapture отображает визуализации кадр за кадром на уровне просмотра, что упрощает проверку состояния просмотра в определенные моменты по сравнению с записями экрана.
На этой странице описано, как подключить ViewCapture к системным приложениям.
Использовать
ViewCapture.java
реализует экземпляр onDrawListener
и собирает трассировку ViewCapture во время процесса рисования. Каждая перерисовка кадра запускает обход иерархии дерева представлений, начиная с корневого представления окна. ViewCapture использует общедоступные методы получения View.java
для извлечения и копирования значений в фоновый поток для повышения производительности. Реализация ViewCapture оптимизирует этот процесс, проверяя, является ли представление «грязным» или недействительным, с помощью captureViewTree
, что позволяет избежать обхода всей иерархии представлений. captureViewTree
доступен только для системных приложений и является частью UnsupportedAppUsage API. Использование этого API ограничено приложениями, основанными на их целевой версии SDK.
Ограничения
В следующих разделах описаны ограничения производительности и памяти при запуске ViewCapture.
Производительность
Средняя задержка основного потока для производительности ViewCapture составляет 195 мкс. Однако в худшем случае это может занять около 5 мс. Обратитесь к срезу vc#onDraw
в трассировке Perfetto .
Накладные расходы в основном обусловлены следующими действиями:
- Обход иерархии занимает 50 мкс, даже при обрезке.
- Извлечение объектов из распределителя свободного списка для хранения копий свойств представления стоит 20 мкс.
- Получение каждого значения свойства с помощью функции получения приводит к множеству дополнительных вызовов функций для каждого представления, что занимает 110 мкс.
Следовательно, включение ViewCapture в режиме постоянной трассировки (AOT) отрицательно влияет на производительность системы и приводит к зависаниям. Из-за ограничений производительности и памяти этот подход не готов к AOT. Мы рекомендуем ViewCapture только для лабораторной и локальной отладки.
Память
Метод Perfetto для трассировок ViewCapture использует один кольцевой буфер, который имеет предопределенный объем памяти для предотвращения чрезмерного использования памяти. Этот подход предотвращает чрезмерное потребление памяти, избегая использования отдельных кольцевых буферов для каждого окна, но не решает проблему хранения всей иерархии представлений для каждого состояния в Perfetto для каждого кадра. Запись одного окна, например NexusLauncher, может создать более 30 секунд данных ViewCapture в буфере размером 10 МБ. Однако для захвата более 30 окон из системного пользовательского интерфейса требуется либо больший буфер, либо значительно более короткое окно времени записи.
Инструкции
Следуйте этим инструкциям, чтобы включить ViewCapture в системные приложения:
Добавьте зависимость в файл
Android.bp
, как показано в коде запуска .android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }
Создайте экземпляр ViewCapture при создании окна, например:
Пример 1 :
private SafeCloseable mViewCapture; @Override protected void onCreate(Bundle savedInstanceState) { ... mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow()); }
Пример 2 :
private SafeCloseable mViewCapture; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (enableViewCaptureTracing()) { mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext()) .startCapture(getRootView(), ".NotificationShadeWindowView"); } ... }
Закройте экземпляр ViewCapture при уничтожении окна, как показано в следующих примерах: