ViewBinding vs Kotlin Android-Erweiterungen mit synthetischen Ansichten

38

Wie vergleicht sich die neue ViewBinding mit den Kotlin Android Extensions mit synthetischen Ansichtsbindungen?

Abgesehen von NullSafety und TypeSafety, die von neuen ViewBindings bereitgestellt werden, warum sollten wir in Betracht ziehen, die Kotlin-Methode zur Verwendung synthetischer Bindungen in Views aufzugeben.

Ist das neue ViewBinding leistungsfähiger, da es die Binding-Klasse zuvor generiert?

Rinav
quelle
Ich habe eine ähnliche Frage auf diskut.kotlinlang erstellt. Wenn jemand Gedanken zu diesem Thema hat,
zögern Sie nicht
1
Weitere Hintergrundinformationen finden Sie in The Argument Over Kotlin Synthetics .
Cheticamp

Antworten:

69

Lassen Sie uns die beiden überprüfen.


Aufbau

Kotlin Android-Erweiterungen

  1. Importieren Sie geeignete synthetische Layouterweiterungen: import kotlinx.android.synthetic.main.<layout>.*
  2. Referenzansichten im Code über ihre IDs : textView.text = "Hello, world!". Diese Erweiterungen arbeiten: Activities, Fragmentsund Views.

Bindung anzeigen

  1. Erstellen Sie eine verbindliche Referenz in Ihrer Klasse: private lateinit var binding YourClassBinding
  2. Blasen Sie Ihre Bindung binding = YourClassBinding.inflate(layoutInflater)in Activityund auf onCreateund rufen Sie setContentView(binding.root)sie auf Fragment, onCreateViewund geben Sie sie dann zurück:return binding.root
  3. Referenzansichten im Code durch Binden unter Verwendung ihrer IDs binding.textView.text = "Hello, world!"

Typensicherheit

Kotlin Android Extensions und ViewBinding sind per Definition typsicher, da referenzierte Ansichten bereits in geeignete Typen umgewandelt wurden.


Null Sicherheit

Kotlin Android Extensions und ViewBinding sind beide null sicher. ViewBinding hat hier keinen Vorteil . Wenn bei KAE die Ansicht nur in einigen Layoutkonfigurationen vorhanden ist, weist IDE Sie darauf hin:

Geben Sie hier die Bildbeschreibung ein

Sie behandeln es also einfach wie jeden anderen nullbaren Typ in Kotlin, und der Fehler verschwindet:

Geben Sie hier die Bildbeschreibung ein


Layoutänderungen anwenden

Bei Kotlin-Android-Erweiterungen führen Layoutänderungen sofort zur Generierung synthetischer Erweiterungen, sodass Sie sie sofort verwenden können. Bei ViewBinding müssen Sie Ihr Projekt erstellen


Falsche Layoutverwendung

Im Fall von Kotlin Android-Erweiterungen ist es möglich, synthetische Erweiterungen mit falschem Layout zu importieren, was zu Ursachen führt NullPointerException. Gleiches gilt für ViewBinding , da wir falsche BindingKlassen importieren können . Obwohl es wahrscheinlicher ist, einen falschen Import als einen falschen Klassennamen zu übersehen, insbesondere wenn die Layoutdatei gut nach Activity/ Fragment/ benannt ist View, hat ViewBinding hier die Oberhand.


Zusammenfassung von KAE vs ViewBinding

  • Typensicherheit - Zeichnen.
  • Null Sicherheit - Unentschieden.
  • Boilerplate-Code - KAE gewinnt. Aus der Dokumentation zu Kotlin Android Extensions :

Mit dem Kotlin Android Extensions-Plugin können wir die gleiche Erfahrung wie mit einigen dieser Bibliotheken erzielen, ohne zusätzlichen Code hinzufügen zu müssen.

  • Layoutänderungen anwenden - KAE gewinnt. Änderungen erfolgen im Gegensatz zu ViewBinding sofort .
  • Falsche Layoutverwendung - ViewBinding gewinnt

Ich denke , es ist ein großes Missverständnis über ViewBinding Sein Ersatz für KAE . Die Leute hören große Schlüsselwörter und wiederholen sie, ohne sie vorher zu überprüfen. Sicher, ViewBinding ist derzeit die beste Option für die Java-Entwicklung (Ersatz für ButterKnife ), aber es gibt keinen oder nur einen geringen Vorteil gegenüber KAE in Kotlin (siehe Abschnitt " Falsche Layoutverwendung ").

Randnotiz: Ich bin sicher, dass DataBinding-Leute ViewBinding mögen werden :)

Xinaiz
quelle
Warum haben Sie nichts über die Verwendung von Variablen in gesagt DataBinding? Ich denke, es ist eine wesentliche Funktion, die Verwendung von Ansichtsreferenzen überhaupt zu beenden. Übrigens können Sie Ihr Ansichtsmodell durch <include ... />Tags "werfen" , was ein weiterer großer Vorteil ist.
Ircover
1
@Ircover Die Frage betraf den Vergleich von KAE und ViewBinding. DataBinding ist kein Teil dieser Frage.
Xinaiz
Hoppla, sorry) Einfaches Missverständnis.
Ircover
1
@ BenLewis Wenn Ihre Bindung als lateinit definiert ist, haben Sie immer noch das gleiche Problem. Das bedeutet, dass Sie beim Schreiben von Code in das Fragment keine strengen Regeln befolgen müssen, wenn Sie KAE oder ViewBinding verwenden.
Flavio
1
"Anwenden von Layoutänderungen" - Wenn Sie ViewBinding verwenden, müssen Sie Ihr Projekt nicht erstellen. Nachdem Sie eine neue Ansicht mit einer ID hinzugefügt haben, können Sie sofort "binding.myTextView .." ausführen.
Tayyab Mazhar
19

ViewBindinglöste das größte Problem von kotlinx.android.synthetic. In syntheticWenn Sie Ihre Inhalte im Hinblick auf eine Layout - Bindung, dann eine ID eingeben , die nur in einem anderen Layout vorhanden ist , können die IDE Sie automatisch vervollständigt und die neue Import - Anweisung hinzuzufügen. Sofern der Entwickler nicht ausdrücklich überprüft, ob seine Importanweisungen nur die richtigen Ansichten importieren, gibt es keine sichere Möglichkeit, um sicherzustellen, dass dies kein Laufzeitproblem verursacht. Aber in ViewBindingSie verwenden sollen layoutverbindlich Objekt seine Ansichten zugreifen , so dass Sie nie invoke zu einer Ansicht in einem anderen Layout und wenn Sie dies tun wollen , müssen Sie einen Compiler - Fehler nicht einen Laufzeitfehler erhalten. Hier ist ein Beispiel.

Wir erstellen zwei Layouts mit dem Namen activity_mainund activity_otherwie folgt:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <TextView
        android:id="@+id/message_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

activity_other.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                >

    <TextView
        android:id="@+id/message_other"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

Wenn Sie Ihre Aktivität nun so schreiben:

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_other.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //Application will crash because "message_other" doesn't exist in "activity_main"
        message_other.text = "Hello!"
    }
}

Ihr Code wird fehlerfrei kompiliert, aber Ihre Anwendung stürzt zur Laufzeit ab. Weil die Ansicht mit der message_otherID in nicht vorhanden ist activity_mainund der Compiler dies nicht überprüft hat. Aber wenn Sie ViewBindingso verwenden:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //This code will never compile and the IDE shows you an error
        binding.message_other.text = "Hello!"
    }
}

Ihr Code wird niemals kompiliert und Android Studiozeigt Ihnen einen Fehler in der letzten Zeile.

Squti
quelle
1
Sie können LayoutInflater auch verwenden, um View aufzublasen und dann über eine Variable auf die definierten Felder zu verweisen.
NapoleonTheCake
4
Dies scheint im realen Szenario sehr unwahrscheinlich zu sein.
Bencri
1
Das Beispiel macht keinen Sinn. Sie haben es falsch verwendet. Warum würden Sie das falsche Ding (activity_other) importieren? Jedes Framework, das Sie falsch verwenden, kann Probleme verursachen.
Android-Entwickler
2

kotlinx.android.synthetic ist keine empfohlene Vorgehensweise mehr, sagte Google in einer Commit-Nachricht "einer von Reddit-Threads

https://android-review.googlesource.com/c/platform/frameworks/support/+/882241 "

Synthetics wird nicht von Google entwickelt, sondern ist Teil der von JetBrains entwickelten Kotlin-Android-Erweiterung. Nach und nach ersetzten Google-Android-Entwickler die Synthetics in ihren Demos und Quellcodes durch die ViewBindins.

"Jetzt kommt die Frage, welche wir berücksichtigen müssen."

Laut Google (View Binding, ButterKnife, Kotlin Synthetics) werden diese Bibliotheken von vielen Apps erfolgreich verwendet und lösen das gleiche Problem.

Für die meisten Apps empfiehlt Google jedoch, die Ansichtsbindung anstelle dieser Bibliotheken auszuprobieren, da die Ansichtsbindung eine sicherere und präzisere Ansichtssuche bietet.

Angehängtes Referenzbild, um Dinge schnell zu löschen. Geben Sie hier die Bildbeschreibung ein

Wenn Sie jedoch in die Abteilung gehen möchten, können Sie dem unten angegebenen Link folgen. https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

SourabhTech
quelle
2
1. Immer null-sicher - Die Ansichtsbindung stürzt immer noch ab, wenn sie vor dem Aufblasen oder nach dem Ende des Ansichtslebenszyklus verwendet wird - nichts anderes als Kunststoffe - sollte für ViewBinding ROT sein. 2. Nur Referenz-IDs aus dem aktuellen Layout - das stimmt, aber IDE zeigt an, aus welchem ​​Layout Sie die angegebene ID importieren möchten, sodass dies kein großes Problem darstellt. 3. Unterstützt Kotlin & Java - schlechtes Argument, wenn Sie Kotlin in der Android-Entwicklung verwenden können, warum dann Java verwenden. 4. Menge des benötigten Codes - Kotlin-Kunststoffe haben die geringste Menge und sollten in der Tabelle sehr niedrig sein.
Xinaiz
@xinaiz Warum Sie es vor dem Aufblasen verwenden, befolgen Sie den richtigen Weg, um es anderweitig zu verwenden, um sicherzugehen, dass Sie mit den Problemen konfrontiert werden. Haben Sie den Link durchgesehen, bevor Sie eine Bewertung abgegeben und den Kommentar medium.com/androiddevelopers/…
SourabhTech
Ja, ich habe es vor einiger Zeit gelesen. Ich benutze es nicht vor dem Aufblasen, ich sage nur, dass es möglich ist. "Richtiger Weg" impliziert, dass es Risiken gibt, oder? Hast du auch einen or after view lifecycle endsTeil übersprungen ?
Xinaiz
@xinaiz 2.Aber es besteht die Möglichkeit, eine falsche ID zu verwenden, wenn das Projekt größer ist, und auch für denselben Ressourcennamen, wenn mehrere Entwickler an einem Projekt arbeiten. 3. Ja, es kann eine Projektanforderung geben, bei der Sie sowohl Java als auch Kotlin verwenden müssen (Wenn das Projekt bereits in Java entwickelt wurde und mit Kotlin begonnen hat, hilft es definitiv). 4. Für Synthetics müssen Sie eine separate Bibliothek importieren, aber für die Ansichtsbindung Es ist bereits in Gradle vorhanden. Es hat also offensichtlich weniger Code benötigt.
SourabhTech
1
Als Antwort auf 4. Welche Bibliothek? Es ist standardmäßig aktiviert. Es ist Streit über apply plugin: 'kotlin-android-extensions'vs viewBinding { enabled = true }. Kein großer Unterschied.
Xinaiz