ViewCapture to narzędzie, które rejestruje właściwości widoków (takie jak lokalizacja, rozmiar, skala i widoczność) w oknach, do których jest podłączone. Funkcja ViewCapture rejestruje informacje o różnych widokach w oknie i ich właściwościach, dzięki czemu możesz dowiedzieć się, jak wyglądają wrażenia użytkownika w określonych momentach i śledzić zmiany w czasie.
Nagrywanie ekranu pozwala wizualizować stan widoku w określonym momencie i pokazywać, jak się zmienia, ale wymaga to znacznych zasobów procesora i może mieć wpływ na wydajność. Narzędzie ViewCapture ma mniejszy wpływ na zasoby i może być częściej włączane. Dodatkowo ViewCapture wyświetla wizualizacje klatka po klatce na poziomie widoku, dzięki czemu łatwiej jest sprawdzić stan widoku w określonych momentach w porównaniu z nagraniami ekranu.
Na tej stronie opisaliśmy, jak włączyć ViewCapture w aplikacji systemowej.
Użyj
ViewCapture.java
implementuje instancję onDrawListener
i zbiera ślad ViewCapture podczas procesu rysowania. Każde ponowne rysowanie ramki powoduje przeszukiwanie hierarchii drzewa widoku, zaczynając od widoku okna skojarzonego z widokiem głównym.
ViewCapture używa publicznych metod View.java
getter, aby pobierać i kopiować wartości do wątku w tle w celu zwiększenia wydajności. Implementacja ViewCapture optymalizuje ten proces, sprawdzając, czy widok jest nieaktualny lub nieprawidłowy za pomocą captureViewTree
, dzięki czemu unika przeszukiwania całej hierarchii widoków. captureViewTree
jest dostępna tylko w przypadku aplikacji systemowych i jest częścią interfejsu UnsupportedAppUsage API.
Korzystanie z tego interfejsu API jest ograniczone do aplikacji, których docelowa wersja pakietu SDK jest zgodna z wymaganiami.
Ograniczenia
W poniższych sekcjach opisaliśmy wydajność i ograniczenia pamięci podczas uruchamiania narzędzia ViewCapture.
Wydajność
Średni czas wykonywania głównego wątku w przypadku funkcji ViewCapture to 195 μs. W najgorszym przypadku może to jednak potrwać około 5 ms. Zapoznaj się z odcinkiem vc#onDraw
w śladzie Perfetto.
Koszty ogólne wynikają głównie z tych działań:
- Przejście przez hierarchię zajmuje 50 μs, nawet po przycięciu.
- Pobieranie obiektów z alokutora listy wolnych elementów w celu przechowywania kopii właściwości widoku kosztuje 20 μs.
- Pobieranie wartości każdej właściwości za pomocą funkcji gettera powoduje wiele dodatkowych wywołań funkcji na widok, co kosztuje 110 μs.
Włączenie funkcji ViewCapture w ramach funkcji Always On Tracing (AOT) negatywnie wpływa na wydajność systemu i powoduje zacinanie. Ze względu na te ograniczenia dotyczące wydajności i pamięci to podejście nie jest gotowe do skompilowania AOT. Zalecamy korzystanie z ViewCapture tylko w laboratorium i do debugowania lokalnego.
Pamięć
Metoda Perfetta dotycząca śladów ViewCapture korzysta z pojedynczego pierścieniowego bufora pamięci, który ma zdefiniowany z góry rozmiar śladu pamięci, aby zapobiec nadmiernemu wykorzystaniu pamięci. Takie podejście zapobiega nadmiernemu zużyciu pamięci, ponieważ nie wymaga korzystania z osobnych buforów pierścieniowych dla każdego okna. Nie rozwiązuje jednak problemu przechowywania całej hierarchii widoku dla każdego stanu w Perfetto w przypadku każdego kadru. Nagranie jednego okna, takiego jak NexusLauncher, może wygenerować ponad 30 sekund danych ViewCapture w buforze o rozmiary 10 MB. Jednak rejestrowanie ponad 30 okienek z interfejsu systemu wymaga albo większego bufora, albo znacznie krótszego okna nagrywania.
Instrukcje
Aby włączyć ViewCapture w aplikacjach systemowych:
Dodaj zależność do pliku
Android.bp
, jak pokazano w kodzie Launchera.android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }
Utwórz instancję ViewCapture podczas tworzenia okna, na przykład:
-
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"); } ... }
-
Zamknij instancję ViewCapture podczas niszczenia okna, jak pokazano w tych przykładach:
-
@Override public void onDestroy() { ... if (mViewCapture != null) mViewCapture.close(); }
-
@Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mViewCaptureCloseable != null) { mViewCaptureCloseable.close(); } ... }
-