ViewBinding vs Kotlin Android Extensions avec des vues synthétiques

38

Comment le nouveau ViewBinding se compare-t-il aux extensions Android Kotlin avec des liaisons de vues synthétiques?

Outre la NullSafety et la TypeSafety fournies par les nouveaux ViewBindings, pourquoi devrions-nous envisager d'abandonner la manière Kotlin d'utiliser des liaisons synthétiques sur les vues.

Le nouveau ViewBinding est-il plus performant car il génère au préalable la classe Binding?

Rinav
la source
J'ai créé une question quelque peu similaire sur discuter.kotlinlang. Si quelqu'un a des réflexions sur le sujet, n'hésitez pas à répondre :)
xinaiz
1
Jetez un œil à The Argument Over Kotlin Synthetics pour en savoir plus.
Cheticamp

Réponses:

69

Passons en revue les deux.


Configuration

Extensions Android Kotlin

  1. Importez les extensions synthétiques de mise en page appropriées: import kotlinx.android.synthetic.main.<layout>.*
  2. Référence vues en code via leur carte d' identité: textView.text = "Hello, world!". Ces extensions fonctionnent sur: Activities, Fragmentset Views.

Voir la reliure

  1. Créez une référence de liaison dans votre classe: private lateinit var binding YourClassBinding
  2. Gonflez votre liaison binding = YourClassBinding.inflate(layoutInflater)dans Activity« s onCreateet un appel setContentView(binding.root), ou le gonfler dans Fragmentl » onCreateViewretour il:return binding.root
  3. Vues de référence dans le code via une liaison à l'aide de leurs identifiants binding.textView.text = "Hello, world!"

Type de sécurité

Les extensions Android Kotlin et ViewBinding sont sécuritaires par définition, car les vues référencées sont déjà converties en types appropriés.


Sécurité nulle

Les extensions Kotlin Android et ViewBinding sont toutes deux sans danger. ViewBinding n'a aucun avantage ici . Dans le cas de KAE , si la vue n'est présente que dans certaines configurations de mise en page, IDE vous le signalera:

entrez la description de l'image ici

Donc, vous le traitez simplement comme n'importe quel autre type nullable dans Kotlin, et l'erreur disparaîtra:

entrez la description de l'image ici


Application des modifications de disposition

Dans le cas des extensions Kotlin Android , les changements de disposition se traduisent instantanément par la génération d'extensions synthétiques, vous pouvez donc les utiliser immédiatement. En cas de ViewBinding , vous devez construire votre projet


Utilisation incorrecte de la mise en page

En cas d' extensions Kotlin Android , il est possible d'importer des extensions synthétiques de mise en page incorrectes, provoquant ainsi NullPointerException. La même chose s'applique à ViewBinding , car nous pouvons importer une mauvaise Bindingclasse. Bien qu'il soit plus probable d'oublier l'importation incorrecte que le nom de classe incorrect, surtout si le fichier de mise en page porte bien le nom de Activity/ Fragment/ View, ViewBinding a donc le dessus ici.


Résumé de KAE vs ViewBinding

  • Type de sécurité - Draw.
  • Sécurité nulle - Draw.
  • Code de la chaudière - KAE gagne. Dans la documentation des extensions Android de Kotlin :

Le plugin Kotlin Android Extensions nous permet d'obtenir la même expérience que nous avons avec certaines de ces bibliothèques, sans avoir à ajouter de code supplémentaire.

  • Appliquer les changements de disposition - KAE gagne. Les modifications sont instantanées contrairement à ViewBinding .
  • Utilisation de mise en page incorrecte - ViewBinding gagne

Je pense qu'il y a une grande idée fausse sur le fait que ViewBinding remplace KAE . Les gens entendent de gros mots clés et les répètent sans les vérifier au préalable. Bien sûr, ViewBinding est la meilleure option pour le développement Java en ce moment (remplacement de ButterKnife ), mais il n'y a pas ou peu d'avantages sur KAE dans Kotlin (voir la section Utilisation incorrecte de la mise en page ).

Note latérale: je suis sûr que les utilisateurs de DataBinding apprécieront ViewBinding :)

xinaiz
la source
Pourquoi n'avez-vous rien dit sur l'utilisation de variables dans DataBinding? Je pense que c'est une fonctionnalité essentielle pour ne plus utiliser de références de vue. Soit dit en passant, vous pouvez "lancer" votre modèle de vue à travers des <include ... />balises, ce qui est un autre gros avantage.
Ircover
1
@Ircover La question portait sur la comparaison de KAE et ViewBinding. La liaison de données ne fait pas partie de cette question.
xinaiz
Oups, désolé) Simple malentendu.
Ircover
1
@BenLewis si votre liaison définie comme Lateinit vous avez toujours le même problème. Cela signifie qu'aucun compteur de ce que vous utilisez KAE ou ViewBinding vous devez suivre certaines règles strictes lors de l'écriture de code dans le fragment.
Flavio
1
"Appliquer les modifications de mise en page" - Lorsque vous utilisez ViewBinding, vous n'avez pas à créer votre projet, après avoir ajouté une nouvelle vue avec un identifiant, vous pouvez instantanément faire "binding.myTextView ..".
Tayyab Mazhar
19

ViewBindingrésolu le plus gros problème de kotlinx.android.synthetic. Dans la syntheticliaison si vous définissez votre vue de contenu sur une mise en page, puis tapez un identifiant qui n'existe que dans une autre mise en page, l'EDI vous permet de compléter automatiquement et d'ajouter la nouvelle instruction d'importation. Sauf si le développeur vérifie spécifiquement que ses instructions d'importation importent uniquement les vues correctes, il n'existe aucun moyen sûr de vérifier que cela ne causera pas de problème d'exécution. Mais ViewBindingvous devez utiliser votre layoutobjet de liaison pour accéder à ses vues afin de ne jamais invoquer une vue dans une disposition différente et si vous voulez le faire, vous obtiendrez une erreur de compilation et non une erreur d'exécution. Voici un exemple.

Nous créons deux mises en page appelées activity_mainet activity_otherainsi:

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>

Maintenant, si vous écrivez votre activité comme ceci:

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!"
    }
}

votre code se compilera sans aucune erreur mais votre application se bloquera lors de l'exécution. Parce que la vue avec message_otherid n'existe pas activity_mainet que le compilateur n'a pas vérifié cela. Mais si vous utilisez ViewBindingcomme ça:

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!"
    }
}

votre code ne sera jamais compilé et Android Studiovous montrera une erreur dans la dernière ligne.

Squti
la source
1
Vous pouvez également utiliser LayoutInflater pour gonfler View, puis référencer ses champs définis via une variable.
NapoleonTheCake
4
Cela semble très peu susceptible de se produire dans un scénario réel.
Bencri
1
L'exemple n'a pas de sens. Vous l'avez mal utilisé. Pourquoi importeriez-vous la chose incorrecte (activity_other)? Chaque framework que vous n'utilisez pas correctement peut provoquer des problèmes.
développeur Android
2

kotlinx.android.synthetic n'est plus une pratique recommandée, a déclaré par google dans un message de validation "l'un des threads Reddit

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

Synthetics n'est pas développé par google, il fait partie de l'extension android kotlin conçue par JetBrains et les développeurs de google android ont progressivement commencé à remplacer les synthétiques par les ViewBindins dans leurs démos et codes sources.

"Maintenant vient la question, laquelle nous devons prendre en considération."

Selon google (View binding, ButterKnife, Kotlin synthetics), ces bibliothèques sont utilisées avec succès par de nombreuses applications et résolvent le même problème.

Mais pour la plupart des applications, Google recommande d'essayer la liaison de vues au lieu de ces bibliothèques, car la liaison de vues offre une recherche de vue plus sûre et plus concise.

Image de référence jointe pour effacer les choses rapidement. entrez la description de l'image ici

Cependant, si vous souhaitez vous rendre dans le département, vous pouvez suivre le lien ci-dessous. https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

SourabhTech
la source
2
1. Toujours null-safe - La liaison de vue se bloquera toujours si elle est utilisée avant l'inflation ou après la fin du cycle de vie de la vue - rien de différent des synthétiques - devrait être ROUGE pour ViewBinding. 2. Ne référencez que les identifiants de la disposition actuelle - c'est vrai, mais l'IDE indique à partir de quelle disposition vous voulez importer l'identifiant donné, donc ce n'est pas un gros problème. 3. Prend en charge Kotlin et Java - mauvais argument, si vous pouvez utiliser Kotlin dans le développement Android, alors pourquoi utiliser Java. 4. Quantité de code nécessaire - Les synthétiques Kotlin ont la plus petite quantité, devraient être très faibles dans le tableau.
xinaiz
@xinaiz Pourquoi vous l'utilisez avant de gonfler, suivez la bonne façon de l'utiliser sinon vous serez certainement confronté aux problèmes. Avez-vous parcouru le lien avant de downvote et de poster le commentaire medium.com/androiddevelopers/…
SourabhTech
Oui, je l'ai lu il y a quelque temps. Je ne l'utilise pas avant de gonfler, je dis juste que c'est possible. "La bonne façon" implique qu'il y a des risques, non? De plus, vous avez sauté une or after view lifecycle endspartie?
xinaiz
@xinaiz 2.Mais il y a une chance d'utiliser un mauvais identifiant si le projet est plus grand et aussi pour le même nom de ressource si plusieurs développeurs travaillent sur le projet. 3.Oui, il peut y avoir une exigence de projet où vous devez utiliser à la fois java et kotlin (Si le projet est déjà développé en java et a commencé l'intrigation avec kotlin, alors cela aide certainement) 4. Pour les synthétiques, vous devez importer une bibliothèque distincte mais pour visualiser la liaison il est déjà là à Gradle, donc évidemment il a fallu moins de code.
SourabhTech
1
En réponse à 4. Quelle bibliothèque? Il est activé par défaut. Il est à propos de l' argument apply plugin: 'kotlin-android-extensions'vs viewBinding { enabled = true }. Pas beaucoup de différence.
xinaiz