如何应对 Android 面试官 -> 玩转 JetPack ViewBinding

前言


本章为 DataBinding 先做个铺垫,讲解下 ViewBinding

ViewBinding 主要是用来释放 findViewById 当我们在实际业务开发中如果不需要 DataBinding 的强大功能的时候(DataBinding 很重,layout 内部复杂,耗费性能),可以使用 ViewBinding;

基础使用


模块的 build.gradle 中,声明 closure

arduino 复制代码
// 启用ViewBinding
viewBinding {
   enabled true
}

和 DataBinding 的启用方式一样;

启用之后,我们就不需要 ButterKnife 以及 findViewById 这种方式了;

我们先来声明 xml 文件,取名叫 activity_main.xml

ini 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/tv3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

代码很简单,就是界面上放了三个 TextView,然后,我们在 Activity 中通过 ViewBinding 将这 xml 和 Activity 关联起来;

当我们通过 studio 创建这个 xml 的时候,gradle 插件就帮我们生成了一个类,根据 activity_main 这个名字生成了一个 ActivityMainBinding 类;然后我们就可以在 Activity 中调用这个类来将 xml 和 Activity 绑定到一起;

scala 复制代码
// ViewBinding背后不是用 APT 注解处理器 使用什么?  答:gradle插件
public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mainBinding.getRoot());

        mainBinding.tv1.setText("AAA");
        mainBinding.tv2.setText("BNB");
        mainBinding.tv3.setText("DDDD");
    }
}

可以看到,ViewBinding 并不需要在 xml 中搞什么复杂的 layout 标签嵌套之类的;也不需要在 Activity 中声明 findViewById 了;

ViewBinding 背后不是用 APT 注解处理器;那么它使用的是什么?答:gradle插件;

通过 gradle 插件提升了编译速度,不像 DataBinding 那么耗费性能;

与 kotlin 绑定机制的差异

接下来讲一下两者的差异

kotlin 的绑定启用

arduino 复制代码
plugins {
    // 有绑定机制后,就不需要 findViewById   gradle插件
    id 'kotlin-android-extensions' // 启用 绑定机制
}

kotlin 的绑定也是在 build.gradle 中启用 kotlin 的一个 gradle 插件;

启用这个插件之后,Activity 中可以直接使用,但是这个必须在 kt 文件中,java 中是不好使的;

kotlin 复制代码
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
// 核心逻辑
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity  : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 绑定机制的缺点
        setContentView(R.layout.activity_main)
        tv1.text = "AAA"
        tv2.text = "BBB"
        tv3.text = "CCC"

    }
}

kotlin 的这个绑定机制有个缺陷,就是可以在当前的 Activity 中绑定任何 xml,但是,我们需要通过 setContentView 绑定 xml 和 Activity,如果在 Activity 中访问了其他 xml 中的元素,就会导致启动崩溃;

kotlin 复制代码
// 绑定机制的缺点1
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.test.*

class MainActivity  : AppCompatActivity() {

    var vb: ActivityMainBinding ? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 绑定机制的缺点2
        setContentView(R.layout.activity_main)
        tv1.text = "AAA"
        tv2.text = "BBB"
        tv3.text = "CCC"
        // 绑定机制的缺点3
        button.text = "" // 人为失误,有隐患,让开发者犯错*/
    }
}

ViewBinding 则不会产生上述的错误;因为我们通过 ViewBinding 只能访问到当前绑定的 xml 中的元素;

Fragment 中的基础使用


java 复制代码
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        FragmentBlankBinding fragmentBlankBinding = FragmentBlankBinding.inflate(getLayoutInflater());
        return fragmentBlankBinding.getRoot();
    }

和 Activity 的用法基本一致;

简单原理


我们开启 ViewBinding 之后,当声明一个 xml 的时候,会自动的在 moudlue -> build -> generated -> data_binding_base_class_source_out 下生成相关的类;

随便打开一个类看下:

本质上还是需要 findViewById 只是它帮我们生成了而已;

好了,ViewBinding 就讲到这里吧,本章只是对 DataBinding 进行一个铺垫,重点讲解 DataBinding,感兴趣的可以继续探索下 ViewBinding 的原理;

欢迎三连


来都来了,点个关注,点个赞吧,你的支持是我最大的动力~

相关推荐
顾林海6 小时前
ViewModel 销毁时机详解
android·面试·android jetpack
雨白17 小时前
Jetpack系列(三):Room数据库——从增删改查到数据库平滑升级
android·android jetpack
雨白2 天前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
刘龙超3 天前
如何应对 Android 面试官 -> 玩转 JetPack LiveData
android jetpack
Wgllss13 天前
Kotlin+协程+FLow+Channel+Compose 实现一个直播多个弹幕效果
android·架构·android jetpack
_一条咸鱼_13 天前
Android Gson注解驱动的转换规则原理(9)
android·面试·android jetpack
_一条咸鱼_13 天前
Android Runtime大对象分配与处理流程原理深度剖析(59)
android·面试·android jetpack
Wgllss14 天前
Kotlin+协程+FLow+Channel,实现生产消费者模式3种案例
android·架构·android jetpack
Wgllss14 天前
6种Kotlin中单例模式写法,特点及应用场景指南
android·架构·android jetpack