1. 基本用法
1.1. @InjectView(R.id.text) textView; 声明View的id
1.2. ButterKnife.inject(this); 将id和View进行关联
2. 特点
2.1. 声明式, 给View类型字段添加额外属性
2.2. 去除冗余代码
3. 实现
3.1. java编译过程, jsr269
3.1.1. 图示
3.2. apt工作原理
3.3. 具体实现
3.3.1. Annotation
3.3.1.1. @Retention(CLASS) @Target(FIELD) public @interface InjectView { int value(); }
3.3.2. ButterKnife.inject 通过反射调用对应Injector.inject方法
3.3.2.1. Class<?> injector = Class.forName(activity.getClass().getName() + AnnotationProcessor.SUFFIX); Method inject = injector.getMethod("inject", activity.getClass()); inject.invoke(null, activity);
3.3.3. AnnotationProcessor
3.3.3.1. 模型 Map<TypeElement, Set<InjectionPoint>>
3.3.3.2. 实现, 两阶段
3.3.3.2.1. 收集@InjectView标记的字段和所在的类型, 存入模型中 Map<className, Set<INjectionPoint>>
3.3.3.2.2. 根据模型生成Injector类, 供ButterKnife调用
3.3.4. META-INF/services/javax.annotation.processing.Processor
3.3.4.1. butterknife.Views$AnnotationProcessor
4. 思考
4.1. 这种库有实际意义吗?
4.1.1. 调用代码的可维护性/可读性?
4.1.2. 去除boilerplate代码, 减少出错几率?