比较 data binding,view binding,Kotlin Synthetics和findViewById 到底要用哪一个?

最近随着Kotlin 1.4.20版本的发布,Android官方宣布将废弃Kotlin Extension的Gradle插件,并且在后续的Kotlin Release版本也不再发布更新了。
Android的Kotlin Extensions插件有两个非常棒的特性:
findViewById,用kotlinx.android.synthetic绑定就能实现。@Parcelize的注解就能实现Parcelable而不用写模板代码。随着这个插件被废弃,我们再也用不到这些特性了。不用担心Parcelize,因为它将作为一个独立的插件发布,叫kotlin-parcelize。但是Kotlin Synthetic真的是要永远说再见了。
现在全球所有的Android开发者都怀着沉重的心情,不得不跟Synthetic说在。但是回过头了,我们得思考一下,为什么一开始极力推荐Synthetic,现在又将它废弃了?现在不能用了,我们又该怎么办呢?
“Necessity is the mother of invention”
早些时候,为了拿到这些带ID的View,我们必须用findViewById。这个方法看起来很简单,但是再开发的过程中确有很多问题。
这个函数通过遍历view的层级结构来找到指定ID的控件。如果找到就立马返回对应的view否则返回null。让我们看一下这种方式的有哪些问题:
然后就出现了像Butter Knife这样的库来简化这个操作。Butter Knife解决了模板代码的问题,但是依然没解决类型安全和空安全的问题。还有就是它使用的是注解会有一丢丢影响打包速度。(注意:Butter Knife现在已经被废弃了。)
随着2017年发布了Android Kotlin Extensions Gradle插件,Kotlin Synthetics来了。对每个布局文件,Kotlin Synthetics会自动创建包含view的类——就是那么简单。你只需要在你的gradle文件里面导入这个插件,view的所有引用变量都配置好了,你可以直接用。
它的内部还是通过findViewById来实现的,只调用一次,然后都是缓存。
这个用起来很方便有趣啊,为什么现在被废弃了。
让我们来分析一下。
优点
缺点
因为这些问题,Kotlin Synthetics现在被废弃了。但是它的替代者是谁呢?我们应该回到之前的findViewById的方式吗?还是有其他推荐的方式?
让我们看一下有哪些推荐的方式:
这篇文档里面提到:“Data Binding是一个通过声明式的方式而不是编程式的形式,让你布局文件里面的UI组件绑定到你APP的数据源的支持库。”
在APP模块下的build.gradle文件开启dataBinding的开关就能用起来了。
- android {
- ...
- buildFeatures {
- dataBinding true
- }
- }
在布局文件里面开启data binding,需要手动添加的标签到布局文件里面。
- <layout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
- <data>
- <variable
- name="viewmodel"
- type="com.myapp.data.ViewModel" />
- data>
- <ConstraintLayout... />
- layout>
Android studio 会自动给你的布局创建一个带Binding后缀的类。比如,你的布局文件名是activity_main.xml,那么Android会自动生成一个叫ActivityMainBinding的类。
Data binding 非常抢到,有以下的几个特性:
优点
缺点
简单的说,View Binding是一个简化的或者说是data binding的一部分。
两个的区别是view binding只是为了做view的引用而不做数据源和UI的绑定。
在APP模块的build.gradle文件开启viewBinding的开关就嫩使用View Binding了。
- android {
- ...
- buildFeatures {
- viewBinding true
- }
- }
- 复制代码
对于ViewBinding,你不需要在你的布局文件里面声明任何东西。所有的布局文件默认都会生成一个带Binding后缀的类文件。
- private lateinit var binding: ResultProfileBinding
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ResultProfileBinding.inflate(layoutInflater)
- val view = binding.root
- setContentView(view)
- }
- binding.name.text = viewModel.name
- binding.button.setOnClickListener { viewModel.userClicked() }
- 复制代码
View binding和data binding都应该是推荐的方式。对于简单的用户场景,用view binding替换Kotlin Synthetics,如果你还在很原始的使用findViewById,你更应该做迁移了。
如果你觉得data binding也很强大,你也可以使用data binding。
还有一种方式就是view binding和data binding都用。那样配置了标签的布局文件就是按data binding的方式工作,其他则是view binding。