ViewBinding vs Kotlin Extensiones de Android con vistas sintéticas

38

¿Cómo se compara el nuevo ViewBinding con las extensiones de Android Kotlin con enlaces de vistas sintéticas?

Además de NullSafety y TypeSafety proporcionadas por los nuevos ViewBindings, ¿por qué deberíamos considerar abandonar la forma de Kotlin de usar enlaces sintéticos en las Vistas?

¿El nuevo ViewBinding tiene más rendimiento ya que genera la clase Binding de antemano?

Rinav
fuente
He creado pregunta algo similar en discuss.kotlinlang. Si alguien tiene pensamientos sobre el tema, no dude en responder :)
xinaiz
1
Eche un vistazo a The Argument Over Kotlin Synthetics para obtener más información.
Cheticamp

Respuestas:

69

Repasemos los dos.


Configuración

Extensiones de Android Kotlin

  1. Importar extensiones sintéticas de diseño apropiadas: import kotlinx.android.synthetic.main.<layout>.*
  2. Referencia vistas de código a través de sus documentos de identidad: textView.text = "Hello, world!". Estas extensiones funcionan en: Activities, Fragmentsy Views.

Ver enlace

  1. Crea una referencia vinculante dentro de tu clase: private lateinit var binding YourClassBinding
  2. Inflar su unión binding = YourClassBinding.inflate(layoutInflater)en el interior Activity's onCreatey llamada setContentView(binding.root), o inflarlo en Fragment' s onCreateViewluego devolverlo:return binding.root
  3. Vistas de referencia en código a través del enlace utilizando sus identificadores binding.textView.text = "Hello, world!"

Tipo de seguridad

Kotlin Android Extensions y ViewBinding son seguros para los tipos por definición, porque las vistas referenciadas ya están convertidas en tipos apropiados.


Seguridad nula

Kotlin Android Extensions y ViewBinding son nulos seguros. ViewBinding no tiene ninguna ventaja aquí . En el caso de KAE , si la vista está presente solo en algunas configuraciones de diseño, IDE lo señalará por usted:

ingrese la descripción de la imagen aquí

Así que solo lo trata como cualquier otro tipo anulable en Kotlin, y el error desaparecerá:

ingrese la descripción de la imagen aquí


Aplicar cambios de diseño

En el caso de las extensiones de Android Kotlin , los cambios de diseño se traducen instantáneamente en la generación de extensiones sintéticas, por lo que puede usarlas de inmediato. En el caso de ViewBinding , debe construir su proyecto


Uso incorrecto del diseño

En el caso de las extensiones de Android Kotlin , es posible importar extensiones sintéticas de diseño incorrecto, causando así NullPointerException. Lo mismo se aplica a ViewBinding , ya que podemos importar una Bindingclase incorrecta . Aunque, es más probable que pase por alto la importación incorrecta que el nombre de clase incorrecto, especialmente si el archivo de diseño está bien nombrado después de Activity/ Fragment/ View, por lo que ViewBinding tiene ventaja aquí.


Resumen de KAE vs ViewBinding

  • Escriba seguridad - Dibujar.
  • Seguridad nula - Dibujar.
  • Código repetitivo : KAE gana. De la documentación de Kotlin Android Extensions :

El complemento Kotlin Android Extensions nos permite obtener la misma experiencia que tenemos con algunas de estas bibliotecas, sin tener que agregar ningún código adicional.

  • Aplicación de cambios de diseño : KAE gana. Los cambios son instantáneos en contraste con ViewBinding .
  • Uso de diseño incorrecto : gana ViewBinding

Creo que hay una gran idea errónea acerca de que ViewBinding es un reemplazo para KAE . La gente escucha palabras clave grandes y las repite sin verificarlas de antemano. Claro, ViewBinding es la mejor opción para el desarrollo de Java en este momento (reemplazo de ButterKnife ), pero no hay o poca ventaja sobre KAE en Kotlin (consulte la sección Uso de diseño incorrecto ).

Nota al margen: estoy seguro de que a la gente de DataBinding le gustará ViewBinding :)

xinaiz
fuente
¿Por qué no dijiste nada sobre el uso de variables DataBinding? Creo que es una característica esencial dejar de usar referencias de vista. Por cierto, puede "lanzar" su modelo de vista a través de <include ... />etiquetas, que es otra gran ventaja.
Ircover el
1
@Ircover La pregunta era sobre la comparación de KAE y ViewBinding. DataBinding no es parte de esa pregunta.
xinaiz
Vaya, lo siento) Simple malentendido.
Ircover el
1
@BenLewis si su enlace definido como lateinit todavía tiene el mismo problema. Eso significa que sin medir lo que usa KAE o ViewBinding, debe seguir algunas reglas estrictas al escribir código en el fragmento.
Flavio
1
"Aplicación de cambios de diseño": al usar ViewBinding, no es necesario que construya su proyecto, después de agregar una nueva vista con una identificación, puede hacer instantáneamente "binding.myTextView ..".
Tayyab Mazhar
19

ViewBindingresuelto el mayor problema de kotlinx.android.synthetic. En el syntheticenlace, si configura su vista de contenido en un diseño, luego escribe una identificación que solo existe en un diseño diferente, el IDE le permite completar automáticamente y agregar la nueva declaración de importación. A menos que el desarrollador verifique específicamente para asegurarse de que sus declaraciones de importación solo importen las vistas correctas, no hay una forma segura de verificar que esto no cause un problema de tiempo de ejecución. Pero ViewBindingdebe usar su layoutobjeto de enlace para acceder a sus vistas para que nunca invoque a una vista en un diseño diferente y, si desea hacerlo, obtendrá un error de compilación, no un error de tiempo de ejecución. Aquí hay un ejemplo.

Creamos dos diseños llamados activity_mainy activity_otherasí:

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>

actividad_otra.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>

Ahora si escribes tu actividad así:

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

su código se compilará sin ningún error, pero su aplicación se bloqueará en tiempo de ejecución. Debido a que la vista con message_otherid no existe activity_mainy el compilador no verificó esto. Pero si usas ViewBindingasí:

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

su código nunca se compilará y le Android Studiomostrará un error en la última línea.

Squti
fuente
1
También puede usar LayoutInflater para inflar Vista y luego hacer referencia a sus campos definidos a través de la variable.
NapoleonTheCake
44
Esto parece muy poco probable que ocurra en el escenario de la vida real.
Bencri
1
El ejemplo no tiene sentido. Lo usaste incorrectamente. ¿Por qué importarías la cosa incorrecta (actividad_otra)? Cada marco que usa incorrectamente puede causar problemas.
Desarrollador de Android
2

kotlinx.android.synthetic ya no es una práctica recomendada, dijo Google en un mensaje de confirmación "uno de los hilos de Reddit

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

Synthetics no está desarrollado por google, es parte de la extensión de Android kotlin creada por JetBrains y gradualmente los desarrolladores de google android comenzaron a reemplazar Synthetics por ViewBindins en sus demos y códigos fuente.

"Ahora viene la pregunta, cuál debemos tener en cuenta".

Según google (View vinculante, ButterKnife, Kotlin sintéticos), muchas bibliotecas utilizan con éxito estas bibliotecas y resuelven el mismo problema.

Pero para la mayoría de las aplicaciones, Google recomienda probar el enlace de vista en lugar de estas bibliotecas, ya que el enlace de vista proporciona una búsqueda de vista más segura y concisa.

Imagen de referencia adjunta para aclarar las cosas rápidamente. ingrese la descripción de la imagen aquí

Sin embargo, si desea ir al departamento, puede seguir el siguiente enlace. https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

SourabhTech
fuente
2
1. Siempre nulo-seguro: el enlace de vista aún se bloqueará si se usa antes de inflar o después de que finalice el ciclo de vida de la vista, nada diferente de los sintéticos, debe estar ROJO para ViewBinding 2. Solo los identificadores de referencia del diseño actual: eso es cierto, pero IDE señala desde qué diseño desea importar la identificación dada, por lo que no es un gran problema. 3. Admite Kotlin y Java: argumento incorrecto, si puede usar Kotlin en el desarrollo de Android, ¿por qué usar Java? 4. Cantidad de código necesaria: Kotlin sintéticos tiene la cantidad más baja, debe ser muy baja en la tabla.
Xinaiz
@xinaiz Por qué lo está usando antes de inflarlo, siga la forma correcta de usarlo de lo contrario para asegurarse de que enfrentará los problemas. ¿Has leído el enlace antes de votar y publicar el comentario medium.com/androiddevelopers/…
SourabhTech
Sí, lo he leído hace algún tiempo. No lo estoy usando antes de inflar, solo digo que es posible. "Forma correcta" implica que hay riesgos, ¿verdad? Además, te saltaste or after view lifecycle endsparte?
Xinaiz
@xinaiz 2.Pero existe la posibilidad de usar una identificación incorrecta si el proyecto es más grande y también para el mismo nombre de recurso si el desarrollador múltiple está trabajando en el proyecto. 3. Sí, puede haber un requisito de proyecto en el que tenga que usar java y kotlin (si el proyecto ya está desarrollado en java y comenzó la intrusión con kotlin, entonces definitivamente ayuda) 4. Para Synthetics debe importar una biblioteca separada pero para ver el enlace ya está allí en Gradle, así que obviamente tomó menos código.
SourabhTech
1
En respuesta a 4. ¿Qué biblioteca? Está habilitado por defecto. Es discusión sobre apply plugin: 'kotlin-android-extensions'vs viewBinding { enabled = true }. No mucha diferencia.
xinaiz