Sposób zarządzania hierarchią
View
obiektu może mieć znaczny wpływ
wydajność aplikacji. Na tej stronie dowiesz się, jak sprawdzić, czy hierarchia widoków spowalnia
aplikacji i strategii rozwiązywania ewentualnych problemów.
Ta strona skupia się na ulepszaniu układów opartych na View
. Informacje na temat ulepszania
Wydajność Jetpack Compose: zobacz Jetpack Compose
skuteczności reklam.
Układ i pomiar skuteczności
Potok renderowania obejmuje etap układu i pomiaru, na którym
odpowiednio umieszcza odpowiednie elementy w hierarchii widoków. Część wskaźnika tego parametru
etapie określa rozmiary i granice obiektów View
. Element dotyczący układu
określa, w którym miejscu na ekranie należy umieścić obiekty View
.
Oba te etapy potoku wiążą się z niewielkim kosztem przetwarzanego widoku lub układu. Większość
jest minimalny i nie wpływa znacząco na wydajność. Jednak może to być większe
gdy aplikacja dodaje lub usuwa obiekty View
, na przykład
RecyclerView
poddaje je recyklingowi lub jest używane ponownie. Koszt może też być wyższy, jeśli obiekt View
wymaga
do rozważenia zmiany rozmiaru,
by sprostać jej ograniczeniom. Jeśli na przykład aplikacja wywołuje
SetText()
w obiekcie View
, który zawija tekst, obiekt View
może wymagać zmiany rozmiaru.
Jeśli taka sytuacja trwa zbyt długo, może to uniemożliwić wyrenderowanie klatki w dozwolonym 16 ms, co może powodować upuszczenie klatek i zakłócanie animacji.
Ponieważ nie możesz przenieść tych operacji do wątku instancji roboczej – aplikacja musi je przetworzyć w wątku głównym – najlepiej jest je zoptymalizować, aby zajmowały jak najmniej czasu.
Zarządzanie złożonymi układami
Układy Androida umożliwiają zagnieżdżanie obiektów UI hierarchii widoków. Takie zagnieżdżanie może też powodować naliczanie opłat za układ. Gdy aplikacja przetwarza obiekt w przypadku układu, aplikacja wykonuje ten sam proces na wszystkich jego elementach podrzędnych.
W przypadku skomplikowanego układu czasami koszt jest naliczany dopiero przy pierwszym obliczeniu przez system
układ. Na przykład, gdy aplikacja odświeża złożony element listy w elemencie RecyclerView
system musi rozmieścić wszystkie obiekty. Innym przykładem są banalne zmiany.
jest rozpowszechniony w kierunku elementu nadrzędnego, aż dotrze do obiektu, który nie ma wpływu na rozmiar
elementu nadrzędnego.
Częstą przyczyną długiego czasu wczytywania układu jest to, że hierarchie obiektów View
są zagnieżdżone w innym miejscu. Każdy zagnieżdżony obiekt układu nalicza opłaty za etap układu. Lepszy
tym mniej czasu zajmie ukończenie etapu układu.
Zalecamy użycie metody
Edytora układów, by utworzyć
ConstraintLayout
, zamiast
RelativeLayout
lub
LinearLayout
, jak jest obecnie
jest ogólnie bardziej efektywne i ogranicza zagnieżdżenie układów. Jednak w przypadku prostych układów,
można osiągnąć za pomocą
FrameLayout
, zalecamy
za pomocą: FrameLayout
.
Jeśli używasz klasy RelativeLayout
, możesz osiągnąć taki sam efekt
niższym kosztem. Zamiast tego użyj zagnieżdżonych, nieważonych widoków LinearLayout
. Pamiętaj jednak:
jeśli używasz zagnieżdżonych, ważonych widoków LinearLayout
, koszt układu jest znacznie wyższy
ponieważ wymaga wielu kart układu, co wyjaśniono w następnej sekcji.
Zalecamy też używanie atrybutu RecyclerView
zamiast atrybutu
ListView
, ponieważ może ona poddawać recyklingowi
układy poszczególnych elementów listy, co zwiększa wydajność i może usprawnić przewijanie.
skuteczność reklam.
Podwójne opodatkowanie
Zwykle platforma wykonuje etap układu lub pomiaru w jednym przejściu. Jednak w skomplikowanych przypadkach układów, struktura może być zmuszona wielokrotnie hierarchii, w której przed ostatecznym umieszczeniem elementów wymagane jest rozwiązanie wielu kart. Mając wykonanie więcej niż jednej iteracji układu i pomiaru to tzw. podwójne i podatku.
Jeśli na przykład korzystasz z kontenera RelativeLayout
, który umożliwia określenie pozycji
View
obiektów względem pozycji innych obiektów View
,
platforma wykonuje tę sekwencję:
- Przeprowadza zaliczenie układu i pomiaru, podczas którego platforma oblicza wartość każdego obiektu podrzędnego pozycji i rozmiaru reklamy w zależności od potrzeb danego dziecka.
- Wykorzystuje te dane, biorąc pod uwagę waga obiektów, do określenia właściwej pozycji powiązane wyświetlenia.
- Wykonuje drugie przejście układu, by zakończyć pozycji.
- Przechodzi do następnego etapu procesu renderowania.
Im więcej poziomów ma Twoja hierarchia widoku, tym większe ryzyko pogorszenia wydajności.
Jak już wspominaliśmy, pakiet ConstraintLayout
jest ogólnie skuteczniejszy niż inne
układy z wyjątkiem: FrameLayout
. Jest mniej podatna na wiele kart układu, a
eliminuje potrzebę zagnieżdżania układów.
Kontenery inne niż RelativeLayout
również mogą zwiększyć podwójne opodatkowanie. Dla:
przykład:
- Widok
LinearLayout
może skutkować podwójnym zaliczeniem układu i wskaźnika, jeśli w poziomie. Podwójny karnet układu i pomiaru może wystąpić również w orientacji pionowej, jeśli dodajmeasureWithLargestChild
, W takim przypadku platforma może potrzebować drugiego etapu, by rozwiązać problemy z odpowiednimi rozmiarami obiektów. GridLayout
także umożliwia pozycjonowanie względne, ale normalnie pozwala uniknąć podwójnego opodatkowania przez wstępne przetwarzanie relacje pozycjonowane między wyświetleniami dzieci. Jeśli jednak układ korzysta z wag lub wypełnieniaGravity
, to korzyść zostanie utracone wstępne przetwarzanie, a platforma może wymagać wykonania wielu kart, jeśli kontener ma statusRelativeLayout
.
Wiele kart z uwzględnieniem układu i pomiarów nie musi obciążać wydajności. Mogą jednak stają się uciążliwym problemem, jeśli trafią w niewłaściwe miejsce. Zachowaj ostrożność w sytuacjach, gdy jeden z następujących elementów warunki mają zastosowanie do Twojego kontenera:
- Jest to główny element w hierarchii widoków.
- Ma głęboką hierarchię widoków.
- Jest wiele sytuacji, w których wypełnia on ekran, podobnie jak dzieci,
ListView
obiekt.
Diagnozuj problemy z hierarchią widoków
Wydajność układu to złożony problem, który obejmuje wiele aspektów. Poniższe narzędzia mogą Ci pomóc określać, gdzie występują wąskie gardła wydajności. Niektóre narzędzia podają mniej jednoznaczne informacje ale mogą też dać pomocne wskazówki.
Perfetto
Perfetto to narzędzie, które dostarcza danych o skuteczności. Śledzenie Androida możesz otworzyć w Perfetto Google Analytics.
Profil renderowania GPU
renderowanie GPU profilu urządzenia. narzędzie, dostępne na urządzeniach z Androidem 6.0 (poziom interfejsu API 23) lub nowszym, dostarcza konkretnych informacji o wąskich gardłach wydajności. To narzędzie pozwala sprawdzić, jak długo dla każdego z nich jest przeprowadzany ramki renderowania. Te dane mogą pomóc w diagnozowaniu problemów z wydajnością środowiska wykonawczego oraz określać, jakie problemy z układem i pomiarami trzeba rozwiązać.
W graficznym przedstawienie przechwytywanych danych funkcja renderowania GPU w profilu używa koloru niebieskim reprezentującym czas układu. Więcej informacji na temat korzystania z tego narzędzia znajdziesz na stronie Szybkość renderowania za pomocą GPU profilu.
Liszka
Narzędzie Lint w Android Studio może ułatwić zorientowanie się i zmniejszają wydajność w hierarchii widoków. Aby użyć tego narzędzia, wybierz kolejno opcje Analizuj > Sprawdź kod, co pokazano na ilustracji 1.
Informacje o różnych elementach układu pojawiają się w sekcji Android > Lint > Skuteczność. Aby wyświetlić więcej szczegółów, kliknij każdy element, aby go rozwinąć. Wyświetl więcej informacji w panelu na po prawej stronie ekranu. Ilustracja 2 przedstawia przykład rozwiniętej informacji.
W panelu po prawej stronie kliknięcie elementu spowoduje wyświetlenie związanych z nim problemów.
Aby dowiedzieć się więcej o konkretnych tematach i problemach w tej dziedzinie, zobacz Dokumentacja Lint.
Narzędzie do inspekcji układu
Narzędzie Inspektor układu w Android Studio zapewnia wizualna reprezentacja hierarchii widoków aplikacji. To dobry sposób na poruszanie się po hierarchii w aplikacji, stanowiąc wyraźną reprezentację łańcucha nadrzędnego danego widoku i sprawdzić układy tworzone przez aplikację.
Widoki wyświetlane przez inspektora układu pomagają też zidentyfikować problemy z wydajnością wynikające o podwójnym opodatkowaniu. Może też służyć do identyfikowania głębokich łańcuchów układów zagnieżdżonych lub obszarów układu z dużą liczbą zagnieżdżonych elementów podrzędnych, co może być źródłem kosztów wydajności. W W takich przypadkach etapy układu i pomiaru mogą być kosztowne i powodować problemy z wydajnością.
Więcej informacji znajdziesz w artykule Debugowanie układu w: z inspektora układu i weryfikacji układu.
Rozwiązywanie problemów z hierarchią widoków
Podstawowa koncepcja rozwiązywania problemów z wydajnością, które powstają w wyniku hierarchii widoków, może w praktyce może być trudny. Zapobieganie nakładaniu kar za wydajność przez hierarchie widoków uproszczenia hierarchii widoków i ograniczenia podwójnego opodatkowania. W tej sekcji omawiamy strategie za realizację tych celów.
Usuń zbędne układy zagnieżdżone
ConstraintLayout
to biblioteka Jetpack z wieloma różnymi mechanizmami pozycjonowania widoków
układ. Pozwala to ograniczyć potrzebę zagnieżdżenia jednej kamery ConstaintLayout
i może pomóc w spłaszczeniu widoku.
w hierarchii. Zazwyczaj łatwiej jest spłaszczyć hierarchie, używając funkcji ConstraintLayout
w porównaniu
do innych typów układów.
Deweloperzy często używają więcej zagnieżdżonych układów, niż jest to konieczne. Na przykład plik
Kontener RelativeLayout
może zawierać pojedynczy element podrzędny, który jest również
RelativeLayout
kontener. Takie zagnieżdżanie jest zbędne i zwiększa zbędny koszt
hierarchię widoków. Program Lint może oznaczyć ten problem za Ciebie, co skróci czas debugowania.
Scal lub uwzględnij
Częstą przyczyną zbędnych układów zagnieżdżonych jest to,
<include>
. Układ wielokrotnego użytku możesz na przykład zdefiniować w ten sposób:
<LinearLayout> <!-- some stuff here --> </LinearLayout>
Następnie możesz dodać tag <include>
, aby dodać do elementu nadrzędnego poniższy element
kontener:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/app_bg" android:gravity="center_horizontal"> <include layout="@layout/titlebar"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello" android:padding="10dp" /> ... </LinearLayout>
Poprzedni układ obejmuje niepotrzebnie zagnieżdżony pierwszy układ w drugim.
<merge>
może pomóc zapobiec temu problemowi. Więcej informacji o tym tagu znajdziesz tutaj:
Użyj funkcji <merge>
.
Wdróż tańszy układ
Być może nie uda Ci się dostosować istniejącego schematu układu, by nie zawierał zbędnych elementów układy. W niektórych przypadkach jedynym rozwiązaniem może być spłaszczenie hierarchii przez przejście na zupełnie innego typu układu.
Możesz na przykład zauważyć, że
TableLayout
udostępnia te same
działa w bardziej złożonym układzie
z wieloma zależnościami pozycjonowymi. Biblioteka Jetpack
ConstraintLayout
udostępnia podobne funkcje co RelativeLayout
oraz oferuje więcej funkcji ułatwiających tworzenie
aby układy były bardziej płaskie i wydajne.