新的ViewBinding与带有合成视图绑定的Kotlin Android扩展相比如何?
除了新的ViewBindings提供的NullSafety和TypeSafety之外,我们为什么还要考虑放弃在视图上使用合成绑定的Kotlin方法。
由于新的ViewBinding事先生成了Binding类,因此它的性能更高吗?
新的ViewBinding与带有合成视图绑定的Kotlin Android扩展相比如何?
除了新的ViewBindings提供的NullSafety和TypeSafety之外,我们为什么还要考虑放弃在视图上使用合成绑定的Kotlin方法。
由于新的ViewBinding事先生成了Binding类,因此它的性能更高吗?
Answers:
让我们回顾两个。
import kotlinx.android.synthetic.main.<layout>.*
textView.text = "Hello, world!"
。这些扩展的工作:Activities
,Fragments
和Views
。private lateinit var binding
YourClassBinding
binding = YourClassBinding.inflate(layoutInflater)
内部Activity
的onCreate
和呼叫setContentView(binding.root)
,或夸大它Fragment
的onCreateView
,然后返回它:return binding.root
binding.textView.text = "Hello, world!"
根据定义,Kotlin Android扩展和ViewBinding是类型安全的,因为已将引用的视图强制转换为适当的类型。
Kotlin Android扩展和ViewBinding都是null安全的。ViewBinding在这里没有任何优势。对于KAE,如果视图仅在某些布局配置中存在,IDE将为您指出:
因此,您只需将其与Kotlin中的其他任何可为null的类型一样对待,错误就会消失:
如果是Kotlin Android扩展,布局更改会立即转换为合成扩展的生成,因此您可以立即使用它们。如果使用ViewBinding,则必须构建您的项目
如果是Kotlin Android扩展程序,则可能会导入不正确的布局合成扩展程序,从而导致NullPointerException
。这同样适用于ViewBinding,因为我们可以导入错误的Binding
类。虽然,比不正确的类名更容易忽略不正确的导入,尤其是在布局文件以Activity
/ Fragment
/ 命名之后View
,因此ViewBinding在这里占了上风。
Kotlin Android扩展插件使我们能够获得与其中某些库相同的体验,而无需添加任何额外的代码。
我认为将ViewBinding替换为KAE有很大的误解。人们会听到较大的关键字,并在没有事先验证的情况下重复它们。可以肯定的是,ViewBinding现在是Java开发的最佳选择(替换ButterKnife),但是在Kotlin中与KAE相比没有优势或几乎没有优势(请参阅不正确的布局用法部分)。
旁注: 我确定DataBinding的人会喜欢ViewBinding的:)
DataBinding
?我认为根本停止使用视图引用是一项重要功能。顺便说一句,您可以通过<include ... />
标签“抛出”视图模型,这是另一个很大的优势。
ViewBinding
解决了最大的问题kotlinx.android.synthetic
。在synthetic
绑定中,如果将内容视图设置为布局,然后键入仅在其他布局中存在的ID,则IDE可以自动完成并添加新的import语句。除非开发人员专门检查以确保其import语句仅导入正确的视图,否则没有安全的方法来验证这不会引起运行时问题。但是在这种情况下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
在最后一行显示错误。
谷歌在一个提交消息中说,kotlinx.android.synthetic不再是推荐做法,“ Reddit线程之一
https://android-review.googlesource.com/c/platform/frameworks/support/+/882241 “
Synthetics不是由Google开发的,而是JetBrains制作的kotlin android扩展的一部分,并且逐渐由google android开发人员开始在其演示和源代码中用ViewBindins替换Synthetics。
“现在问题来了,我们必须考虑哪一个。”
根据谷歌(视图绑定,ButterKnife,科特林合成),这些库已被许多应用程序成功使用,并解决了相同的问题。
但是对于大多数应用程序,谷歌建议尝试使用视图绑定而不是这些库,因为视图绑定提供了更安全,更简洁的视图查找。
但是,如果您想进入部门,则可以点击下面的链接。 https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc
or after view lifecycle ends
一部分?
apply plugin: 'kotlin-android-extensions'
vs 的争论viewBinding { enabled = true }
。没有太大的区别。