Butterknife 源码分析,android 开发环境搭建实验报告
https://www.wanandroid.com/article/query?k=butterknife
Android主流三方库源码分析(七、深入理解ButterKnife源码)
1、Butterknife 原理
===================
讲到 butterknife 的原理。这里不得不提一下一般这种注入框架都是运行时注解,即声明注解的生命周期为 RUNTIME,然后在运行的时候通过反射完成注入,这种方式虽然简单,但是这种方式多多少少会有性能的损耗。那么有没有一种方法能解决这种性能的损耗呢? ??没错,答案肯定是有的,那就是 Butte
rknife 用的 APT(Annotation Processing Tool)编译时解析技术。
注意:Butterknife 是不使用反射的。
APT 大概就是你声明的注解的生命周期为 CLASS,然后继承 AbstractProcessor 类。继承这个类后,在编译的时候,编译器会扫描所有带有你要处理的注解的类,然后再调用 AbstractProcessor 的 process 方法,对注解进行处理,那么我们就可以在处理的时候,动态生成绑定事件或者控件的 java 代码,然后在运行的时候,直接调用 bind 方法完成绑定。
其实这种方式的好处是我们不用再一遍一遍地写 findViewById 和 onClick 了,这个框架在编译的时候帮我们自动生成了这些代码,然后在运行的时候调用就行了。
2、源码解析
======
版本:
//butterknife
implementation 'com.jakewharton:butterknife:10.2.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
拿到源码的第一步是从我们调用的地方来突破,那我们就来看看程序里面是怎样调用它的呢?
@BindView(R.id.btn100)
Button btn100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick(R.id.btn100)
public void onViewClicked() {
}
我们直接就从?**ButterKnife.bind(this)**入手吧,点进来看看:
@NonNull @UiThread
public static Unbinder bind(@NonNull Activity target) {
View sourceView = target.getWindow().getDecorView();
return bind(target, sourceView);
}
根据 activity 得到 DecorView,再传递到 bind。
@NonNull @UiThread
public static Unbinder bind(@NonNull Object target, @NonNull View source) {
Class<?> targetClass = target.getClass();
if (debug) Log.d(TAG, "Looking up binding for " + targetClass.getName());
Constructor<? extends Unbinder> constructor =
findBindingConstructorForClass(targetClass);
if (constructor == null) {
return Unbinder.EMPTY;
}
//noinspection TryWithIdenticalCatches Resolves to API 19+ only type.
try {
return constructor.newInstance(target, source);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unable to invoke " + constructor, e);
} catch (InstantiationException e) {
throw new RuntimeException("Unable to invoke " + constructor, e);
} catch (InvocationTargetException e) {
评论