Zoptymalizuj hierarchie układu

Wypróbuj metodę Compose
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak pracować z układami w Compose.

Powszechnie panuje błędne przekonanie, że korzystanie z podstawowych struktur układu prowadzi do najbardziej wydajnych układów. Każdy widżet i układ dodany do aplikacji wymaga jednak inicjowania, układania i rysowania. Na przykład używanie zagnieżdżonych instancji LinearLayout może prowadzić do nadmiernie rozbudowanej hierarchii widoków. Ponadto zagnieżdżanie kilku instancji tagu LinearLayout, które używają parametru layout_weight, może być szczególnie kosztowne, ponieważ każdy element podrzędny musi być mierzony dwukrotnie. Jest to szczególnie ważne, gdy układ jest wielokrotnie powiększany, np. w przypadku używania go w RecyclerView.

Z tego dokumentu dowiesz się, jak za pomocą narzędzia Layout Inspectorlint sprawdzać i optymalizować układ.

Sprawdzanie układu

Narzędzia pakietu Android SDK zawierają Inspektora układu, który umożliwia analizowanie układu podczas działania aplikacji. To narzędzie pomaga wykrywać nieefektywności w wydajności układu.

Inspektor układu umożliwia wybieranie uruchomionych procesów na podłączonym urządzeniu lub emulatorze, a następnie wyświetlanie drzewa układu. Sygnalizacja świetlna na każdym bloku reprezentuje jego wydajność w zakresie pomiaru, układu i rysowania, co pomaga wykrywać potencjalne problemy.

Na przykład na rysunku 1 przedstawiono układ, który jest używany jako element w RecyclerView. Ten układ zawiera mały obraz bitmapowy po lewej stronie i 2 elementy tekstowe ułożone jeden na drugim po prawej stronie. Szczególnie ważne jest, aby zoptymalizować takie układy, które są rozszerzane wielokrotnie, ponieważ korzyści związane z wydajnością są wtedy zwielokrotnione.

Obraz przedstawiający pojedynczy element na liście: 1 obraz i 2 teksty ułożone pionowo
Rysunek 1. Koncepcyjny układ elementu w RecyclerView.

[narzędzie] Layout Inspector wyświetla listę dostępnych urządzeń i ich działających komponentów. Na karcie Windows (Okna) wybierz komponent i kliknij Layout Inspector (Inspektor układu), aby wyświetlić hierarchię układu wybranego komponentu. Na przykład na rysunku 2 przedstawiono układ elementu listy zilustrowanego na rysunku 1.

Ilustracja przedstawiająca narzędzie Layout Inspector i kompozycję LinearLayout
Rysunek 2. Hierarchia układu w przypadku układu na rysunku 1 z użyciem zagnieżdżonych instancji elementu LinearLayout.

Zmienianie układu

Poprzedni układ działa wolniej z powodu zagnieżdżonego elementu LinearLayout. Możesz poprawić wydajność, spłaszczając układ, czyli sprawiając, że będzie on płytki i szeroki, a nie wąski i głęboki. Węzeł główny AConstraintLayout umożliwia takie układy. Gdy przekształcisz ten projekt, aby używać ConstraintLayout, układ stanie się 2-poziomową hierarchią:

    <androidx.constraintlayout.widget.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/root"
      android:layout_width="match_parent"
      android:layout_height="52dp"
      android:background="#e4e6e4"
      android:padding="4dp">

      <ImageView
          android:id="@+id/image"
          android:layout_width="48dp"
          android:layout_height="48dp"
          android:background="#5c5c74"
          android:contentDescription="An example box"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/title"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:layout_marginStart="4dp"
          android:background="#745c74"
          app:layout_constraintBottom_toTopOf="@+id/subtitle"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toEndOf="@id/image"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/subtitle"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:background="#7e8d6e"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@id/title"
          app:layout_constraintTop_toBottomOf="@+id/title" />
  </androidx.constraintlayout.widget.ConstraintLayout>
    

Sprawdzanie nowego układu wygląda tak:

Ilustracja przedstawiająca narzędzie Layout Inspector 3D
Rysunek 3. Tryb 3D w narzędziu Layout Inspector.

Korzyści z tego rozwiązania są zwielokrotnione, ponieważ ten układ jest używany w przypadku każdego elementu na liście.

Większość różnic wynika z użycia layout_weight w projekcie LinearLayout, co może spowolnić pomiary. To jeden z przykładów, jak każdy układ może być odpowiednio wykorzystany. Zastanów się, czy używanie wagi układu jest konieczne.

W przypadku niektórych złożonych układów system może niepotrzebnie mierzyć ten sam element interfejsu więcej niż raz. To zjawisko nazywa się podwójnym opodatkowaniem. Więcej informacji o podwójnym opodatkowaniu i sposobach jego uniknięcia znajdziesz w sekcji Skuteczność i hierarchie widoków.

Użyj kłaczka

Warto uruchomić narzędzie lint w plikach układu, aby wyszukać możliwe optymalizacje hierarchii widoków. Lint zastępuje narzędzie layoutopt i ma większą funkcjonalność. Oto przykłady reguł lint:

  • Używaj złożonych elementów rysowalnych. Element LinearLayout zawierający ImageViewTextView możesz wydajniej obsługiwać jako złożony obiekt rysowalny.
  • Scal ramkę główną. Jeśli elementem głównym układu jest element FrameLayout, który nie zapewnia tła ani dopełnienia, możesz zastąpić go tagiem merge, który jest nieco bardziej wydajny.
  • Usuń niepotrzebne liście. Możesz usunąć układ, który nie zawiera elementów podrzędnych lub nie ma tła (ponieważ jest niewidoczny), aby uzyskać bardziej płaską i wydajną hierarchię układu.
  • Usuń niepotrzebne elementy nadrzędne. Możesz usunąć układ z elementem podrzędnym, który nie ma elementów równorzędnych, nie jest układem ScrollView ani układem głównym i nie ma tła. Możesz też przenieść widok podrzędny bezpośrednio do widoku nadrzędnego, aby uzyskać bardziej płaską i wydajną hierarchię układu.
  • Unikaj głębokich układów. Układy z zbyt dużą liczbą zagnieżdżeń negatywnie wpływają na wydajność. Aby zwiększyć skuteczność, rozważ użycie prostszych układów, np. ConstraintLayout. Domyślna maksymalna głębokość sprawdzania kodu to 10.

Kolejną zaletą narzędzia lint jest jego integracja z Android Studio. Lint jest uruchamiany automatycznie przy każdej kompilacji programu. W Android Studio możesz też uruchamiać inspekcje lint dla konkretnego wariantu kompilacji lub dla wszystkich wariantów kompilacji.

Możesz też zarządzać profilami kontroli i konfigurować kontrole w Android Studio, wybierając Plik > Ustawienia > Ustawienia projektu. Wyświetli się strona Konfiguracja inspekcji z obsługiwanymi inspekcjami:

Obraz pokazujący menu Inspekcje w Android Studio
Rysunek 4. stronie Konfiguracja inspekcji.

Lint może automatycznie rozwiązywać niektóre problemy, podpowiadać rozwiązania innych i przechodzić bezpośrednio do problematycznego kodu w celu sprawdzenia.

Więcej informacji znajdziesz w sekcjach UkładyZasób układu.