Android renderuje interfejs, generując ramkę z aplikacji i wyświetlając ją na ekranie. Jeśli Twoja aplikacja wolno renderuje się w interfejsie, system jest zmuszony do pomijania klatek. W takiej sytuacji użytkownik widzi na ekranie cykliczne migotanie. Nazywamy to zacinaniem.
Zacinanie się zwykle jest spowodowane spowolnieniem lub zablokowaniem wywołania asynchronicznego w wątku UI (w większości aplikacji jest to wątek główny). Możesz użyć śledzenia systemu, aby zidentyfikować problem.
Wykrywanie zacięć na Androidzie 12 lub nowszym
W przypadku urządzeń z Androidem 12 (poziom interfejsu API 31) lub nowszym przechwycony log czasu jest wyświetlany na ścieżce Janky frame w panelu Display w programie profilującym procesora.
Aby wykryć zacięcie,
W Android Studio wybierz Widok > Okna narzędzi > Profiler lub kliknij Profil na pasku narzędzi.
Jeśli pojawi się okno Wybierz cel wdrożenia, wybierz urządzenie, na którym chcesz wdrożyć aplikację w celu profilowania. Jeśli urządzenie, które podłączysz przez USB, nie ma go na liście, sprawdź, czy debugowanie USB jest włączone.
Kliknij dowolne miejsce na osi czasu CPU, aby otworzyć program profilujący CPU.
Wybierz System Trace z menu konfiguracji w narzędziu do profilowania procesora i kliknij Record. Po zakończeniu interakcji z aplikacją kliknij Zatrzymaj.
W sekcji Displayowe powinna pojawić się ścieżka Janky frame Domyślnie profiler pokazuje tylko nieczytelne klatki jako kandydujące do zbadania. W każdej nieregularnej klatce czerwona część podświetla czas, przez jaki klatka upłynęła po upływie terminu renderowania.
Gdy znajdziesz nieczytelną klatkę, kliknij ją. Opcjonalnie możesz nacisnąć M, aby dostosować powiększenie, aby zaznaczyć wybraną klatkę. W tych wątkach wyróżnione są odpowiednie zdarzenia: wątek główny, RenderThread i GPU Ukończenie.
Opcjonalnie możesz zobaczyć wszystkie klatki lub rozbicie czasu renderowania. Aby to zrobić, zaznacz pola wyboru Wszystkie klatki i Cykl życia.
Wykrywanie zacięć na Androidzie 11
W przypadku urządzeń z Androidem 11 (poziom interfejsu API 30) przechwycony ślad jest wyświetlany w sekcji Cykl życia ramki w programie profilującym procesora.
Sekcja Cykl życia ramki zawiera nazwę warstwy i 4 ścieżki. Każda ścieżka reprezentuje 1 etap procesu renderowania ramki. Elementy Cykl życia ramki:
- Cykl życia ramki (nazwa warstwy): tytuł sekcji zawiera nazwę warstwy w nawiasach. Warstwa to jedna jednostka kompozycji.
- Aplikacja: ta ścieżka zawiera czas od momentu, w którym aplikacja znalazła się w kolejce, do umieszczenia bufora w kolejce do ponownego umieszczenia w kolejce. Zwykle odpowiada to zdarzeniom logu czasu w:
RenderThread
. - Poczekaj na GPU: ta ścieżka pokazuje, jak długo bufor należy do GPU. Jest to czas od momentu wysłania bufora do GPU do zakończenia pracy w buforze przez GPU. Nie oznacza to, że w tym czasie GPU tylko działa w tym buforze. Aby uzyskać szczegółowe informacje o tym, jak działa GPU w danym okresie, skorzystaj z narzędzia Android GPU Inspector.
- Kompozycja: ta ścieżka dźwiękowa pokazuje czas od chwili, gdy SurfaceFlinger zostanie połączony z buforem i wyśle go w celu utworzenia kompozycji, do momentu wysłania bufora do wyświetlacza.
- Wyświetlane klatki: ta ścieżka pokazuje, jak długo klatka była widoczna na ekranie.
Sekcja Cykl życia ramki pokazuje, jak bufor ramki przemieszcza się między różnymi etapami potoku renderowania. Ramki są oznaczone kolorami według numeru, co ułatwia śledzenie poszczególnych klatek.
Android Studio pokazuje też wszystkie klatki w śladzie w formacie tabeli na karcie Wszystkie klatki.
Kolumny Numer klatki, Aplikacja, Poczekaj na GPU i Kompozycja zawierają te same dane co ścieżki w sekcji Cykl życia ramki (patrz wyżej). Kolumna Czas trwania ramki podaje czas od początku działania Aplikacja do rozpoczęcia działania funkcji Klatki na ekranie. Jest to w zasadzie czas potrzebny na pełne renderowanie klatki.
Tabelę ramek możesz posortować według dowolnej kolumny, aby szybko znaleźć najkrótszą lub najdłuższą klatkę. Tabela obsługuje też elementy sterujące podziału na strony, które ułatwiają nawigację między setkami klatek.
Aby wykryć i zbadać zacięcie na Androidzie 11, wykonaj te czynności:
Posortuj tabelę Wszystkie klatki według kolumny Aplikacja w kolejności malejącej, tak by jako pierwsze pojawiały się klatki o najdłuższej długości.
Znajdź najdłużej aktywne klatki i wybierz wiersz tabeli. Spowoduje to powiększenie wybranej klatki w widoku osi czasu po lewej stronie.
Poszukaj odpowiednich wątków w sekcjach Cykl życia ramki i Wątki.
Wykrywanie zacinania na Androidzie 10 i starszych
W przypadku urządzeń z Androidem 10 (poziom interfejsu API 29) lub starszym odpowiednie informacje o potoku grafiki systemu operacyjnego są wyświetlane w pojedynczej sekcji śledzenia systemu profilu procesora o nazwie Display.
- Klatki: ta sekcja przedstawia wątek UI i zdarzenia śledzenia
RenderThread
w aplikacji. Zdarzenia dłuższe niż 16 ms są oznaczone kolorem czerwonym, by wyróżnić potencjalne nieczytelne klatki, ponieważ przekraczają one termin renderowania z szybkością 60 klatek na sekundę (kl./s). - SurfaceFlinger: ta sekcja pokazuje, kiedy SurfaceFlinger przetwarza bufory ramek. SurfaceFlinger to proces systemowy, który odpowiada za wysyłanie buforów do wyświetlenia.
- VSYNC: ta sekcja wyświetla VSYNC, sygnał, który synchronizuje potok displayowy. Ścieżka wyświetla sygnał aplikacji VSYNC-app, który wskazuje, kiedy aplikacja zaczyna się zbyt późno. Zwykle dzieje się tak, gdy wątek UI jest zajęty. Powoduje to, że w trakcie animacji na ekranie pojawia się widoczne migotanie, a także opóźnienia w ich działaniu do czasu zakończenia animacji lub przewijania. Jest to szczególnie ważne w przypadku wyświetlaczy z dużą częstotliwością odświeżania, ponieważ mogą pojawiać się częściej niż 60 razy na sekundę lub ze zmienną szybkością.
- BufferQueue: ta sekcja pokazuje, ile buforów ramek zostało dodanych do kolejki i czeka na wykorzystanie SurfaceFlinger. W przypadku aplikacji wdrożonych na urządzeniach z Androidem 9 (poziom interfejsu API 28) lub nowszym ta ścieżka pokazuje liczbę buforów BufferQueue (
0
,1
lub2
). BufferQueue pomaga w zrozumieniu stanu buforów obrazów przenoszonych między komponentami grafiki Androida. Na przykład wartość2
oznacza, że aplikacja jest obecnie potrójnie buforowana, co powoduje dodatkowe opóźnienie danych wejściowych.
Sekcja Wyświetlanie zawiera przydatne sygnały umożliwiające wykrywanie potencjalnych zacięć, np. gdy wątek UI lub RenderThread
trwa dłużej niż 16 ms. Aby dokładnie sprawdzić, co spowodowało zacinanie, możesz przejrzeć sekcję Wątki, w której znajdziesz wątki związane z renderowaniem UI.
Na rysunku powyżej sekcja Threads zawiera wątek interfejsu (java.com.google.samples.apps.iosched
), RenderThread
i wątek GPU completion
. Są to wątki związane z renderowaniem UI i mogą przyczyniać się do zacinania.
Aby wykryć zacinanie w Androidzie 10 lub starszym, wykonaj te czynności:
Spójrz na ścieżkę Klatki na stronie Displayowe. Czerwone ramki są przedmiotem badań.
Gdy znajdziesz potencjalnie nieczytelną klatkę, powiększ obraz, naciskając
W
lub przewijając kółko myszy, przytrzymując Control (Command w systemie macOS). Powiększaj widok, aż zobaczysz zdarzenia śledzenia w wątku UI iRenderThread
.Na ilustracji powyżej funkcja
Choreographer#doFrame
pokazuje, kiedy wątek interfejsu wywołujeChoreographer
w celu koordynowania animacji, układu widoku, rysowania obrazów i powiązanych procesów.DrawFrames
pokazuje, kiedyRenderThread
tworzy i wydaje do GPU rzeczywiste polecenia rysowania.Jeśli zobaczysz wyjątkowo długie zdarzenie śledzenia, możesz powiększyć widok i sprawdzić, co mogło przyczynić się do powolnego renderowania. Na ilustracji powyżej widać pole
inflate
w wątku interfejsu, co oznacza, że aplikacja poświęca czas na szlifowanie układu. Po powiększeniu jednego ze zdarzeńinflate
możesz dokładnie sprawdzić, ile czasu zajmuje każdy z komponentów UI, jak pokazano poniżej.
Więcej informacji
Aby dowiedzieć się więcej o tym, jak ograniczyć zacinanie, przeczytaj artykuł Typowe źródła zacinania.