Jetpack ViewBinding源码分析
说明
开启ViewBinding后,编译时会扫码layout目录下所有的布局文件,并生成对应的绑定类,这是油gradle插件完成的。生成的绑定类放在build/generated/data_binding_base_class_source_out/debug/out/<包名>/databinding
目录下。
源码分析
// Generated by view binder compiler. Do not edit!
package com.example.jetpack.databinding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewbinding.ViewBinding;
import com.example.jetpack.R;
import java.lang.NullPointerException;
import java.lang.Override;
import java.lang.String;
public final class ActivityVbBinding implements ViewBinding {
@NonNull
private final LinearLayout rootView;
@NonNull
public final Button btn;
@NonNull
public final ImageView ivAvatar;
@NonNull
public final TextView tvAge;
@NonNull
public final TextView tvName;
private ActivityVbBinding(@NonNull LinearLayout rootView, @NonNull Button btn,
@NonNull ImageView ivAvatar, @NonNull TextView tvAge, @NonNull TextView tvName) {
this.rootView = rootView;
this.btn = btn;
this.ivAvatar = ivAvatar;
this.tvAge = tvAge;
this.tvName = tvName;
}
@Override
@NonNull
public LinearLayout getRoot() {
return rootView;
}
@NonNull
public static ActivityVbBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, null, false);
}
@NonNull
public static ActivityVbBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(R.layout.activity_vb, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}
@NonNull
public static ActivityVbBinding bind(@NonNull View rootView) {
// The body of this method is generated in a way you would not otherwise write.
// This is done to optimize the compiled bytecode for size and performance.
int id;
missingId: {
id = R.id.btn;
Button btn = rootView.findViewById(id);
if (btn == null) {
break missingId;
}
id = R.id.iv_avatar;
ImageView ivAvatar = rootView.findViewById(id);
if (ivAvatar == null) {
break missingId;
}
id = R.id.tv_age;
TextView tvAge = rootView.findViewById(id);
if (tvAge == null) {
break missingId;
}
id = R.id.tv_name;
TextView tvName = rootView.findViewById(id);
if (tvName == null) {
break missingId;
}
return new ActivityVbBinding((LinearLayout) rootView, btn, ivAvatar, tvAge, tvName);
}
String missingId = rootView.getResources().getResourceName(id);
throw new NullPointerException("Missing required view with ID: ".concat(missingId));
}
}
- 从生成的绑定类中可以看到,先调用
inflate()
方法再调用bind()
方法,而bind()
方法本质是通过调用findViewById
获取控件对象。 getRoot()
获取的根布局是LinearLayout,是通过LayoutInflate#inflate()
加载获取的。- 与ButterKnife不同的是,ButterKnife是运行时生成,通过APT注解实现的;鸡儿ViewBinding是编译时生成,通过gradle插件扫描layout文件生成的绑定类。