Расширения ViewBinding против Kotlin для Android с синтетическими представлениями - PullRequest
8 голосов
/ 12 октября 2019

Как новые ViewBinding сравниваются с Kotlin Android Extensions с синтетическими привязками видов?

Помимо NullSafety и TypeSafety, предоставляемых новыми ViewBindings, почемумы рассматриваем отказ от использования Kotlin способа использования синтетических привязок в представлениях.

Является ли новый ViewBinding более производительным, так как он генерирует класс Binding заранее?

Ответы [ 2 ]

8 голосов
/ 19 октября 2019

Давайте рассмотрим два.


Конфигурация

Расширения Kotlin Android

  1. Импорт соответствующих расширений синтетического макета: import kotlinx.android.synthetic.main.<layout>.*
  2. Ссылочные виды в коде через их идентификаторы: textView.text = "Hello, world!". Эти расширения работают на: Activities, Fragments и Views.

Просмотреть привязку

  1. Создать ссылку привязки внутри вашего класса: private lateinit var binding YourClassBinding
  2. Накачать привязку binding = YourClassBinding.inflate(layoutInflater) внутри Activity onCreate и позвоните setContentView(binding.root), или надуйте его в Fragment onCreateView, а затем верните: return binding.root
  3. Ссылочные представления в коде через привязку с использованием их идентификаторов binding.textView.text = "Hello, world!"

Безопасность типов

Расширения Kotlin для Android и ViewBinding по определению безопасны по типу, поскольку ссылочные представления уже приведены к соответствующим типам.


Нулевая безопасность

Расширения Kotlin для Android и ViewBinding оба являются нулевыми. ViewBinding здесь не имеет никаких преимуществ . В случае KAE , если представление присутствует только в некоторых конфигурациях компоновки, IDE укажет вам это:

enter image description here

Таким образом, вы просто рассматриваете его как любой другой обнуляемый тип в Kotlin, и ошибка исчезнет:

enter image description here


Применение изменений макета

В случае Kotlin Android Extensions изменения макета мгновенно преобразуются в генерацию синтетических расширений, поэтому вы можете использовать их сразу. В случае ViewBinding , вы должны построить свой проект


Неправильное использование макета

В случае Kotlin Android Extensions , этовозможно импортировать неверные макеты синтетических расширений, в результате чего NullPointerException. То же самое относится к ViewBinding , так как мы можем импортировать неправильный Binding класс. Хотя более вероятно пропустить неправильный импорт, чем неправильное имя класса, особенно если файл макета имеет правильное имя в честь Activity / Fragment / View, поэтому ViewBinding имеет преимущество.


Сводка KAE и ViewBinding

  • Тип безопасности - Ничья.
  • Нулевая безопасность - Ничья.
  • Код котельной - KAE выигрывает. Из Kotlin Android Extensions документация :

Плагин Kotlin Android Extensions позволяет нам получить тот же опыт, что и у нас с некоторыми из этих библиотек, без необходимости добавлять какие-либо дополнительныекод.

  • Применение изменений макета - KAE побед. Изменения происходят мгновенно в отличие от ViewBinding .
  • Неправильное использование макета - ViewBinding wins

Я думаю, что существует большое заблуждение о том, что ViewBinding является заменой KAE . Люди слышат большие ключевые слова и повторяют их без предварительной проверки. Конечно, ViewBinding является лучшим вариантом для разработки Java прямо сейчас (замена ButterKnife ), но в Kotlin нет или мало преимуществ по сравнению с KAE (см. * 1149)* Неправильное использование макета раздел).

Примечание: Я уверен, что людям, связывающим данные, понравится ViewBinding:)

3 голосов
/ 23 октября 2019

ViewBinding решил самую большую проблему kotlinx.android.synthetic. В привязке synthetic, если вы задаете представление содержимого для макета, а затем введите идентификатор, который существует только в другом макете, среда IDE позволяет выполнять автозаполнение и добавлять новый оператор импорта. Если разработчик не проверит, чтобы убедиться, что его операторы импорта импортируют только правильные представления, нет безопасного способа убедиться, что это не вызовет проблем во время выполнения. Но в ViewBinding вы должны использовать объект привязки layout для доступа к его представлениям, чтобы вы никогда не вызывали представление в другом макете, и если вы захотите это сделать, вы получите ошибку компиляции, а не ошибку времени выполнения. Вот пример.

Мы создаем два макета с именами activity_main и activity_other примерно так:

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>

Теперь, если вы напишите свою активность следующим образом:

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

, ваш код скомпилируется без ошибок, но ваше приложение будет аварийно завершать работу во время выполнения. ,Поскольку представление с message_other id не существует в activity_main, и компилятор не проверял это. Но если вы используете ViewBinding следующим образом:

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

, ваш код никогда не скомпилируется, а Android Studio покажет вам ошибку в последней строке.

...