ViewBinding vs Kotlin Android Розширення з синтетичними видами


38

Як новий ViewBinding порівнюється з розширеннями Android в Kotlin із прив’язками синтетичних поглядів?

Окрім форми NullSafety та TypeSafety, що надаються новими ViewBindings, чому ми повинні розглянути можливість відмови від способу Котліна із застосуванням синтетичних прив’язок на Views.

Чи є новий ViewBinding більш ефективним, оскільки він генерує клас зв’язування перед рукою?


Я створив дещо подібне питання на дискусії.kotlinlang. Якщо у когось є думки з цієї теми,
сміливо

1
Погляньте на аргумент над синтетикою Котліна, щоб дізнатися більше.
Cheticamp

Відповіді:


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 Extensions та ViewBinding є безпечними за визначенням, тому що посилання, що посилаються, вже передаються у відповідні типи.


Нульова безпека

Kotlin Android Extensions та ViewBinding - безпечні для нуля. ViewBinding тут не має жодної переваги . У випадку KAE , якщо перегляд присутній лише в деяких конфігураціях макета, IDE вказує на це:

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

Таким чином, ви просто ставитесь до цього як до будь-якого іншого зведеного типу в Котліні, і помилка зникне:

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


Застосування змін макета

У разі розширень Android Kotlin , зміни макета миттєво переводяться на покоління синтетичних розширень, тож ви можете скористатися ними відразу. У випадку ViewBinding ви повинні створити свій проект


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

У випадку розширень Android від Kotlin можливо імпортувати неправильні синтетичні розширення макета, тим самим спричиняючи NullPointerException. Це ж стосується ViewBinding , оскільки ми можемо імпортувати неправильний Bindingклас. Хоча, більш імовірно не помітити неправильний імпорт, ніж неправильне ім’я класу, особливо якщо файл компонування добре названий на Activity/Fragment / View, тому ViewBinding має верх.


Підсумок KAE проти ViewBinding

  • Тип безпеки - Малюємо.
  • Нульова безпека - Нічия.
  • Код котла - виграє KAE . З документації про розширення Android для Kotlin :

Плагін Kotlin Android Extensions дозволяє нам отримати той самий досвід, який ми маємо з деякими з цих бібліотек, без необхідності додавати зайвий код.

  • Застосовуючи зміни макета - виграє KAE . Зміни миттєві на відміну від ViewBinding .
  • Неправильне використання макета - ViewBinding виграє

Я думаю, що існує велика помилка щодо того, що ViewBinding замінює KAE . Люди чують великі ключові слова та повторюють їх, не перевіряючи їх попередньо. Звичайно, ViewBinding - найкращий варіант для розробки Java зараз (заміна ButterKnife ), але немає переваги перед KAE в Котліні (див. Див.) Розділ Неправильне використання макета ).

Побічна примітка: Я впевнений, що DataBinding людям сподобається ViewBinding :)


Чому ви нічого не сказали про використання змінних DataBinding? Я думаю, що це найважливіша особливість взагалі припинити використання посилань на перегляд. До речі, ви можете «кинути» свою модель перегляду через <include ... />теги, що є ще однією великою перевагою.
Ircover

1
@Ircover Питання стосувалося порівняння KAE та ViewBinding. Обв’язання даних не є частиною цього питання.
xinaiz

Ну, вибачте) Просте непорозуміння.
Ircover

1
@BenLewis, якщо ваш зв'язок визначений як lateinit, у вас все ще є та сама проблема. Це означає, що без метри, у якій ви використовуєте KAE або ViewBinding, ви повинні дотримуватися деяких суворих правил, коли пишете код у фрагменті.
Флавіо

1
"Застосування змін у макеті" - Використовуючи ViewBinding, вам не потрібно будувати проект, додавши новий вид з ідентифікатором, ви можете миттєво зробити "obavez.myTextView ..".
Таяб Мажар

19

ViewBindingвирішили найбільшу проблему Росії kotlinx.android.synthetic. У syntheticзв'язуванні , якщо ви встановите вид контент на макет, а потім введіть ідентифікатор , який існує тільки в іншому макеті, середовище дозволяє автозаповнення і додати новий оператор імпорту. Якщо розробник спеціально не перевіряє, чи впевнені, що їх заяви про імпорт лише імпортують правильні представлення даних, немає безпечного способу підтвердити, що це не спричинить проблеми з часом виконання. Але в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_otherid не існує, 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показує вам помилку в останньому рядку.


1
Ви також можете використовувати LayoutInflater для надування View, а потім посилання на його визначені поля через змінну.
NapoleonTheCake

4
Це здається дуже малоймовірним у реальному житті.
Bencri

1
Приклад не має сенсу. Ви використали його неправильно. Чому ви імпортуєте неправильну річ (activity_other)? Кожна рамка, яку ви неправильно використовуєте, може спричинити проблеми.
андроїд розробник

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 синтетика) ці бібліотеки успішно використовуються багатьма програмами і вирішують ту саму проблему.

Але для більшості додатків google рекомендує спробувати прив'язку подання замість цих бібліотек, оскільки прив'язка перегляду забезпечує безпечніший та більш стислий пошук.

Додане довідкове зображення для швидкого очищення речей. введіть тут опис зображення

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


2
1. Завжди безпечний для нуля - прив'язка перегляду все одно вийде з ладу, якщо використовуватись до інфляції або після закінчення життєвого циклу перегляду - нічого, що відрізняється від синтетики, повинно бути ЧЕРВЕНО для ViewBinding. 2. Тільки довідкові ідентифікатори поточного макета - це правда, але IDE вказує, з якого макета потрібно імпортувати даний ідентифікатор, тому це не велика проблема. 3. Підтримує Kotlin & Java - поганий аргумент, якщо ви можете використовувати Kotlin в розробці Android, то навіщо використовувати Java. 4. Необхідна кількість коду - синтетика Котліна має найменшу кількість, в таблиці повинна бути дуже низькою.
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 }. Не велика різниця.
синаїз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.