Расширения ViewBinding и Kotlin для Android с синтетическими представлениями

38

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

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

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

Rinav
источник
Я создал несколько похожий вопрос на обсуждения .kotlinlang. Если у кого-то есть мысли по этой теме, не стесняйтесь отвечать :)
xinaiz
1
Взгляните на Argument Over Kotlin Synthetics для получения дополнительной информации.
Четикамп

Ответы:

69

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


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

Расширения 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«s onCreateи вызов setContentView(binding.root), или раздуть его в Fragment» ы onCreateViewзатем вернуть его:return binding.root
  3. Ссылочные представления в коде через привязку с использованием их идентификаторов binding.textView.text = "Hello, world!"

Тип безопасности

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


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

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

введите описание изображения здесь

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

введите описание изображения здесь


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

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


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

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


Резюме KAE против ViewBinding

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

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

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

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

Примечание: я уверен, что пользователям DataBinding понравится ViewBinding :)

xinaiz
источник
Почему вы ничего не сказали об использовании переменных в DataBinding? Я думаю, что это важная особенность - вообще не использовать ссылки на представления. Кстати, вы можете «бросить» модель представления через <include ... />теги, что является еще одним большим преимуществом.
Ircover
1
@Ircover Вопрос был о сравнении KAE и ViewBinding. Привязка данных не является частью этого вопроса.
xinaiz
Ой, простите) Простое недоразумение.
Ircover
1
@BenLewis, если ваша привязка определена как lateinit, у вас все еще есть та же проблема. Это означает, что независимо от того, используете ли вы KAE или ViewBinding, вы должны соблюдать некоторые строгие правила при написании кода во фрагменте.
Флавио
1
«Применение изменений макета» - при использовании ViewBinding вам не нужно создавать свой проект, после добавления нового представления с идентификатором вы можете мгновенно выполнить «binding.myTextView ..».
Тайяб Мажар
19

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идентификатором не существует, 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покажет вам ошибку в последней строке.

Squti
источник
1
Вы также можете использовать LayoutInflater для раздувания View, а затем ссылаться на его определенные поля через переменную.
NapoleonTheCake
4
Это кажется маловероятным в реальной жизни.
Бенкри
1
Пример не имеет смысла. Вы использовали это неправильно. Почему вы импортируете неправильную вещь (activity_other)? Каждый неправильно используемый фреймворк может вызвать проблемы.
Android-разработчик
2

kotlinx.android.synthetic больше не является рекомендуемой практикой, говорится в сообщении Google в одном сообщении о коммите "одна из веток Reddit

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

Синтетика не разработана Google, она является частью расширения kotlin android, созданного JetBrains, и постепенно разработчики google android начали заменять Synthetics на ViewBindins в своих демоверсиях и исходных кодах.

«Теперь возникает вопрос, какой из них мы должны принять это во внимание».

Согласно Google (Просмотр связывания, ButterKnife, Kotlin synthetics) эти библиотеки успешно используются многими приложениями и решают одну и ту же проблему.

Но для большинства приложений Google рекомендует попробовать привязку представлений вместо этих библиотек, поскольку привязка представлений обеспечивает более безопасный и краткий просмотр представлений.

Прикрепленное контрольное изображение, чтобы быстро очистить вещи. введите описание изображения здесь

Однако, если вы хотите пойти в отдел, вы можете перейти по приведенной ниже ссылке. https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

SourabhTech
источник
2
1. Всегда нулевой - Привязка к представлению будет по-прежнему зависать, если она используется до завершения инфляции или после завершения жизненного цикла представления - ничем не отличающегося от синтетики - должна быть КРАСНАЯ для ViewBinding 2. Только ссылочные идентификаторы из текущего макета - это правда, но IDE указывает, из какого макета вы хотите импортировать данный идентификатор, так что это не большая проблема. 3. Поддерживает Kotlin & Java - плохой аргумент, если вы можете использовать Kotlin в разработке для Android, тогда зачем использовать Java. 4. Количество необходимого кода - синтетика Kotlin имеет наименьшее количество, должно быть очень низким в таблице.
Xinaiz
@xinaiz Почему вы используете его перед надуванием, следуйте правильному способу его использования, иначе вы наверняка столкнетесь с проблемами. Вы прошли по ссылке до downvote и размещения комментария medium.com/androiddevelopers/...
SourabhTech
Да, я читал это некоторое время назад. Я не использую его перед надуванием, я просто говорю, что это возможно. «Правильный путь» подразумевает, что есть риски, верно? Кроме того, вы пропустили or after view lifecycle endsчасть?
Xinaiz
@xinaiz 2. Но есть шанс использовать неправильный идентификатор, если проект больше, а также для того же имени ресурса, если над проектом работает несколько разработчиков. 3.Да может быть требование проекта, где вы должны использовать оба java и kotlin (если проект уже разработан в java и начал работу с kotlin, то это определенно помогает) 4. Для Synthetics вам нужно импортировать отдельную библиотеку, но для привязки вида это уже есть в Gradle, так что, очевидно, это заняло меньше кода.
SourabhTech
1
В ответ на 4. Какая библиотека? Это включено по умолчанию. Это аргумент о apply plugin: 'kotlin-android-extensions'против viewBinding { enabled = true }. Не большая разница.
Xinaiz