Warum sind verschachtelte Gewichte schlecht für die Leistung? Alternativen?

160

Ich habe einige Layoutdateien geschrieben, in denen ich das layout_weightAttribut verwendet habe, um ein Verhältnis zwischen verschiedenen Ansichten zu erstellen.

Irgendwann bekomme ich Flusenwarnungen über verschachtelte Gewichte.

Daher frage ich mich, warum verschachtelte Gewichte die Leistung beeinträchtigen und ob es eine effizientere Möglichkeit gibt, ein konstantes Verhältnis zwischen Ansichtsdimensionen zu erstellen, die für verschiedene Bildschirmgrößen verwendet werden können und für die nicht viele Dimensions-dpi-Werte angegeben werden müssen durch mehrere Layoutdateien (für verschiedene Bildschirmgrößen meine ich).

Danke dir!

MobileCushion
quelle
2
Ein großartiger Beitrag für die Layoutoptimierung developer.android.com/training/improving-layouts/…
Muhammad Babar

Antworten:

140

Verschachtelte Gewichte sind schlecht für die Leistung, weil:

Für Layoutgewichte muss ein Widget zweimal gemessen werden. Wenn ein LinearLayout mit Gewichten ungleich Null in einem anderen LinearLayout mit Gewichten ungleich Null verschachtelt ist, steigt die Anzahl der Messungen exponentiell an.

Es ist besser, RelativeLayouts zu verwenden und Ihre Ansicht an die Orte anderer Ansichten anzupassen, ohne bestimmte dpi-Werte zu verwenden.

CD
quelle
87
Gut zu wissen, was wohl der Zweck der Nachricht ist. Ich würde bemerken, dass eine exponentielle Auswirkung immer noch winzig ist, wenn der betroffene Exponent klein ist. Wenn Sie in kleinen Verschachtelungstiefen nicht die dafür erforderliche CPU verwenden, haben Sie ein Arbeitstier, das Sie die ganze Woche über verwöhnen und nur sonntags spazieren gehen. Für große Verschachtelungstiefen ist dies jedoch ein guter Punkt.
Carl
14
RelativeLayout muss außerdem zweimal gemessen werden, um sicherzustellen, dass alle untergeordneten Layouts korrekt sind. Ändern Sie daher LinearLayout mit Layoutgewicht in RelativeLayout, um die Leistung möglicherweise nicht zu verbessern.
Piasy
Relatives Layout funktioniert nicht immer. In Fällen, in denen Sie proportionale Widgets
Abdurakhmon
67

Update: Wie wir wissen, ist die prozentuale Support-Bibliothek von API-Level 26 veraltet. Dies ConstraintLayoutist der neue Weg, um dieselbe flache XML-Struktur zu erreichen.

Aktualisiertes Github-Projekt

Aktualisierte Beispiele:

<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/fifty_thirty"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffff8800"
        android:gravity="center"
        android:text="@string/fifty_fifty_text"
        android:textColor="@android:color/white"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        android:textSize="25sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffff5566"
        android:gravity="center"
        android:text="@string/fifty_fifty_text"
        android:textColor="@android:color/white"
        android:textSize="25sp"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintLeft_toRightOf="@id/fifty_thirty"
        app:layout_constraintTop_toBottomOf="@id/fifty_thirty"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />

</android.support.constraint.ConstraintLayout>

Update: Gute Nachrichten Android Prozent Support-Bibliothek löst unser Problem der Leistung und verschachtelt chaotisch gewichtetLinearLayout

compile 'com.android.support:percent:23.0.0'

Demo HIER

Betrachten Sie dieses einfache Layout, um dasselbe zu demonstrieren.

Prozent unterstützen libray Demo

<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/fifty_huntv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ff7acfff"
        android:text="20% - 50%"
        android:textColor="@android:color/white"
        app:layout_heightPercent="20%"
        app:layout_widthPercent="50%" />
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_toRightOf="@id/fifty_huntv"
        android:background="#ffff5566"
        android:text="80%-50%"
        app:layout_heightPercent="80%"
        app:layout_widthPercent="50%"
        />

</android.support.percent.PercentRelativeLayout>

Vermeideter Leistungsabbau mit Gewichten verschachtelt. LinearLayoutWirklich großartig !!!.

nitesh
quelle
@dan Ja, wenn man bedenkt, dass wir ein lineares Layout mit Gewichten verschachtelt haben.
Nitesh
3
"Diese Klasse war in API-Level 26.0.0-beta1 veraltet. Verwenden Sie stattdessen ConstraintLayout und zugehörige Layouts." developer.android.com/reference/android/support/percent/…
saiyancoder
7
Ich mag ConstraintLayout nicht. Es verhält sich für mich nicht intuitiv
Carson Holzheimer
8
Das ConstraintLayout ist so schwierig für mich
BertKing
1
Vielleicht sind die Erklärungen von Apple zu Autolayout-Einschränkungen klarer, und da die Logik dieselbe ist, kann sie helfen. Leider finde ich das ConstraintLayout von Droiden schwerer / ausführlicher als das AutoLayout von iOS
AdricoM
46

Ich denke (und ich werde wahrscheinlich dafür geflammt sein), aber ich denke wieder, dass mein Telefon einen Quad-Core-Prozessor hat, der den meisten Heim-PCs der meisten Leute Konkurrenz macht (wenn nicht sogar völlig zerstört).

Ich denke auch, dass diese Art von Hardware-Fähigkeit die Zukunft von Telefonen ist.

Daher komme ich zu dem Schluss, dass es Ihrem Telefon weniger wichtig sein könnte, solange Sie nicht vom Verschachteln mitgerissen werden (in MHO sollte ein Layout niemals mehr als 4 Ebenen tief sein, und wenn Sie es wahrscheinlich falsch machen) über Gewichte haben.

Es gibt viele Dinge, die Sie tun können, die sich weitreichender auf die Leistung auswirken, als sich Sorgen zu machen, dass Ihr Prozessor zusätzliche Berechnungen durchführt.

(Bitte beachten Sie, dass ich ein wenig humorvoll bin und daher nichts zu ernst nehme, außer der Idee, dass es andere Dinge gibt, die Sie zuerst optimieren sollten, und dass die Sorge um ein 2-3-stufiges tiefes Gewicht nicht hilft Ihre Gesundheit)

WIllJBD
quelle
2
genommen und im Wesentlichen einverstanden, aber haben gehört, dass die durchschnittliche Nutzung des iPhones (einschließlich der Webservices / Website, die die Nutzung unterstützen) ungefähr die gleiche Energiemenge pro Jahr wie der durchschnittliche US-Haushaltskühlschrank hat. Es liegt daher in unserer Verantwortung als Entwickler, diese Art von Umweltauswirkungen zu berücksichtigen. Natürlich ist es immer ein Balanceakt: Zeit, Kosten, Leistung, Stabilität, und im Allgemeinen stimme ich Ihrer Perspektive zu - aber denken Sie nur, wir sollten auch diese Art von Auswirkungen berücksichtigen. Natürlich kommt auch hier Wartung / Erweiterbarkeit ins Spiel. Wie auch immer - Punkt gemacht und danke.
MemeDeveloper
Zu erkennen, dass es bei dem fraglichen Punkt um die Verarbeitung auf dem Gerät geht, nicht um das Web, sondern um meinen Kommentar als allgemeinen Punkt über Prioritäten als Entwickler mehr als die Besonderheiten des OP.
MemeDeveloper
11

Der Hauptgrund, warum verschachtelte Gewichte schlecht sind, ist, dass ein Layout, wenn es Kinder mit einem Gewicht hat, zweimal gemessen werden muss (ich denke, dies wird in der Flusenwarnung erwähnt). Dies bedeutet, dass ein gewichtetes Layout, das auch ein gewichtetes Layout enthält, viermal gemessen werden muss und jede 'Schicht' von Gewichten, die Sie hinzufügen, die Maße mit einer Zweierpotenz erhöht.

In ICS (API Level 14) GridLayoutwurde das hinzugefügt, das einfache und "flache" Lösungen für viele Layouts ermöglicht, für die zuvor Gewichte erforderlich waren. Wenn Sie für frühere Versionen von Android entwickeln, fällt es Ihnen etwas schwerer, Gewichte zu entfernen. Wenn Sie jedoch ein RelativeLayoutLayout verwenden und es so weit wie möglich reduzieren, entfernen Sie normalerweise viele der verschachtelten Gewichte.

Jave
quelle
9
Ich glaube nicht, dass Sie mit GridLayout oder die gleichen Ergebnisse erzielen können RelativeLayout. Beispiel GridLayout: "GridLayout bietet keine Unterstützung für das im Gewicht definierte Gewichtsprinzip. Im Allgemeinen ist es daher nicht möglich, ein GridLayout so zu konfigurieren, dass überschüssiger Speicherplatz auf mehrere Komponenten verteilt wird."
Timmmm
Ab API 21 wurde der Gewichtsbegriff zu GridLayout hinzugefügt. Um ältere Android-Geräte zu unterstützen, können Sie das GridLayout aus der v7-Unterstützungsbibliothek verwenden. android.support.v7.widget.GridLayout
gelвансгелист Evansgelist
2

Es gibt eine einfache Lösung, um verschachtelte LinearLayouts mit Gewichten zu vermeiden. Verwenden Sie einfach Tablelayout mit Gewichtssumme und verschachteltes LinearLayout mit weightSum. Tablelayout hat dieselben Attribute wie LinearLayout (Ausrichtung, Gewichtssumme, Layoutgewicht usw.) und zeigt keine Meldung an - "verschachtelte Gewichte schlecht für die Leistung haben "

Beispiel:

 <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="1">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.8"/>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:weightSum="1">


            <ImageView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="0.4"/>

            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="0.6"/>


            </LinearLayout>

    </TableLayout>
eneyovich
quelle
1

Ich denke, die einzige Alternative besteht darin, eine Funktion zu erstellen, die onResume heißt und alle Größen und Positionen festlegt. Wie auch immer, nach Gewicht können Sie nur Größen einstellen, aber keine Polster (damit Layouts noch komplizierter werden), keine Textgrößen (die irgendwie nicht kompensiert werden können), geschweige denn die Anzahl der Zeilen.

Gangnus
quelle