101

新的ViewBinding与带有合成视图绑定的Kotlin Android 扩展相比如何?

除了新的 ViewBindings 提供的 NullSafety 和 TypeSafety 之外,我们为什么要考虑放弃 Kotlin 在 Views 上使用合成绑定的方式?

新的 ViewBinding 是否更高效,因为它预先生成了 Binding 类?

4

4 回答 4

152

让我们回顾一下两者。


配置

Kotlin Android 扩展

  1. 导入适当的布局合成扩展:import kotlinx.android.synthetic.main.<layout>.*
  2. 通过 id 引用代码中的视图:textView.text = "Hello, world!". 这些扩展适用于ActivitiesFragmentsViews

视图绑定

  1. 在您的类中创建绑定引用:private lateinit var binding YourClassBinding
  2. binding = YourClassBinding.inflate(layoutInflater)Activity'sonCreate和 call中膨胀你的绑定,或者在'ssetContentView(binding.root)中膨胀它然后返回它:FragmentonCreateViewreturn binding.root
  3. 通过使用它们的 id 绑定来引用代码中的视图binding.textView.text = "Hello, world!"

类型安全

Kotlin Android ExtensionsViewBinding在定义上是类型安全的,因为引用的视图已经被转换为适当的类型。


零安全

Kotlin Android ExtensionsViewBinding都是 null 安全的。ViewBinding 在这里没有任何优势。在KAE的情况下,如果视图仅存在于某些布局配置中,IDE 会为您指出:

在此处输入图像描述

因此,您只需将其视为 Kotlin 中的任何其他可为空的类型,错误就会消失:

在此处输入图像描述


应用布局更改

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获胜

我认为ViewBinding替代KAE存在很大的误解。人们听到大关键字并重复它们而无需事先验证。当然,ViewBinding是目前 Java 开发的最佳选择(替代ButterKnife ),但在 Kotlin 中与KAE相比没有或几乎没有优势(请参阅不正确的布局使用部分)。

旁注: 我相信 DataBinding 的人会喜欢 ViewBinding :)

于 2019-10-19T15:42:19.217 回答
46

ViewBinding解决了最大的问题kotlinx.android.synthetic。在synthetic绑定中,如果您将内容视图设置为布局,然后键入仅存在于不同布局中的 id,IDE 允许您自动完成并添加新的导入语句。除非开发人员专门检查以确保他们的导入语句只导入正确的视图,否则没有安全的方法来验证这不会导致运行时问题。但是ViewBinding你应该使用你的layout绑定对象来访问它的视图,这样你就永远不会调用不同布局中的视图,如果你想这样做,你会得到一个编译错误而不是运行时错误。这是一个例子。

我们创建了两个布局activity_mainactivity_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在最后一行显示错误。

于 2019-10-23T14:37:16.953 回答
13

Kotlin Android Extensions 已在 Kotlin 1.4.20 中弃用,因此我建议使用 ViewBinding。

https://proandroiddev.com/migrating-the-deprecated-kotlin-android-extensions-compiler-plugin-to-viewbinding-d234c691dec7

于 2020-11-05T13:28:33.963 回答
9

kotlinx.android.synthetic 不再是推荐的做法,谷歌在一个提交消息“Reddit 线程之一”中说

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

Synthetics不是由 google 开发的,它是 JetBrains 制作的 kotlin android 扩展的一部分,并且逐渐 google android 开发人员开始在他们的演示和源代码中用 ViewBindins 替换 Synthetics。

“现在问题来了,我们必须考虑哪一个。”

根据 google(视图绑定、ButterKnife、Kotlin 合成)的说法,这些库已被许多应用程序成功使用并解决了相同的问题。

但是对于大多数应用程序,谷歌建议尝试视图绑定而不是这些库,因为视图绑定提供了更安全、更简洁的视图查找。

附上参考图像以快速清除事物。 在此处输入图像描述

但是,如果您想进入部门,可以按照以下链接进行操作。 https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

于 2020-03-10T12:22:12.117 回答