}
});
target.footer = Utils.findRequiredViewAsType(source, R.id.footer, “field ‘footer’”, TextView.class);
target.headerViews = Utils.listOf(
Utils.findRequiredView(source, R.id.title, “field ‘headerViews’”),
Utils.findRequiredView(source, R.id.subtitle, “field ‘headerViews’”),
Utils.findRequiredView(source, R.id.hello, “field ‘headerViews’”));
}
@Override
@CallSuper
public void unbind() {
T target = this.target;
if (target == null) throw new IllegalStateException(“Bindings already cleared.”);
target.title = null;
target.subtitle = null;
target.hello = null;
target.listOfThings = null;
target.footer = null;
target.headerViews = null;
view2130968578.setOnClickListener(null);
view2130968578.setOnLongClickListener(null);
view2130968578 = null;
((AdapterView<?>) view2130968579).setOnItemClickListener(null);
view2130968579 = null;
this.target = null;
}
}
#####ButterKnife 的执行流程
总的来说,大概可以分为以下几步:
- 在编译的时候扫描注解,并做相应的处理,生成 java 代码,生成 Java 代码是调用 javapoet 库生成的。
- 当我们调用 ButterKnife.bind(this); 方法的时候,他会根据类的全限定类型,找到相应的代码,并执行。完成 findViewById 和 setOnClick ,setOnLongClick 等操作。
第一步:在编译的时候扫描注解,并做相应的处理,生成 java 代码。这一步,可以拆分为几个小步骤:
- 定义我们的注解,声明我们的注解是否保存到 java doc 中,可以作用于哪些区域(Filed ,Class等),以及是源码时注解,编译时注解还是运行时注解等)
- 继承 AbstractProcessor,表示支持哪些类型的注解,支持哪些版本,
- 重写 process 方法,处理相关的注解,存进 Map 集合中
- 根据扫描到的注解信息(即 Map 集合),调用 javapoet 库生成 Java 代码。
#####butterknife-annotations 讲解
我们知道 ButterKnife 自定义很多的注解,有 BindArray,BindBitmap,BindColor,BindView 等,这里我们以 BindView 为例子讲解就 OK 了,其他的也是基本类似的,这里就不再讲解了。
//编译时注解
@Retention(CLASS)
//成员变量, (includes enum constants)
@Target(FIELD)
public @interface BindView {
/** View ID to which the field will be bound. */
@IdRes int value();
}
#####Processor 解析器说明
我们先来看一些基本方法:在 init 方法里面得到一些辅助工具类,这样有一个好处,确保工具类是单例的,因为 init 方法只会在初始化的时候调用。
public synchronized void init(ProcessingEnvironment env) {
super.init(env);
//辅助工具类
elementUtils = env.getElementUtils();
typeUtils = env.getTypeUtils();
filer = env.getFiler();
}
接着重写 getSupportedAnnotationTypes 方法,返回我们支持的注解类型。
@Override
public Set getSupportedAnnotationTypes() {
Set types = new LinkedHashSet<>();
for (Class<? extends Annotation> annotation : getSupportedAnnot