|
| 1 | +## APT |
| 2 | + |
| 3 | +全称 Annotation Processing Tool,即注解处理器,在编译时通过注解生成代码,应用于ButterKnife,EventBus等流行框架 |
| 4 | + |
| 5 | +### ButterKnife原理 |
| 6 | + |
| 7 | +通过APT获取到修饰@BindView等的注解,获取到注解修饰信息后,对当前绑定对象,在当前包目录下后生成后缀**_ViewBinding**的Java文件,里面则是对**findViewById**,点击监听的代码的封装,而对注解修饰变量的赋值时机,是在**ButterKnife#bind**方法中,方法内部调用**_ViewBinding**类的构造方法,进行了属性注入 |
| 8 | + |
| 9 | +### EventBus原理 |
| 10 | + |
| 11 | +传统的方式是在**register**方法中扫描被**@Subscribe**修饰的方法,在合适的时机进行调用,用APT生成扫描后的文件索引,优化了耗时的反射扫描操作,[详细源码分析](http://www.jianshu.com/p/08fa335dddf9) |
| 12 | + |
| 13 | +### 操作 |
| 14 | + |
| 15 | +1. 创建一个注解,[有关注解](https://github.com/TruthKeeper/Note/blob/master/Android/Annotation.md) |
| 16 | +2. 创建一个Java Library(依赖大量javax包下的类) |
| 17 | +3. .gradle如下 |
| 18 | +``` |
| 19 | +apply plugin: 'java' |
| 20 | +
|
| 21 | +dependencies { |
| 22 | + compile fileTree(include: ['*.jar'], dir: 'libs') |
| 23 | + //生成META-INF的信息 |
| 24 | + compile 'com.google.auto.service:auto-service:1.0-rc3' |
| 25 | + //优雅的生成Java代码(可选) |
| 26 | + compile 'com.squareup:javapoet:1.9.0' |
| 27 | + compile project(':annotation') |
| 28 | +} |
| 29 | +// 解决build警告:编码GBK的不可映射字符 |
| 30 | +tasks.withType(JavaCompile) { |
| 31 | + options.encoding = "UTF-8" |
| 32 | +} |
| 33 | +sourceCompatibility = "1.7" |
| 34 | +targetCompatibility = "1.7" |
| 35 | +``` |
| 36 | +4. 继承**AbstractProcessor**,建议通过方法来实现支持的源码版本和处理的注解集合(兼容性有待测试) |
| 37 | +``` |
| 38 | +//生成 META-INF 信息 |
| 39 | +@AutoService(Processor.class) |
| 40 | +//支持的源码版本 |
| 41 | +@SupportedSourceVersion(SourceVersion.RELEASE_7) |
| 42 | +//处理的注解 |
| 43 | +@SupportedAnnotationTypes({"注解全名"}) |
| 44 | +public class AnnotationProcessor extends AbstractProcessor { |
| 45 | + /** |
| 46 | + * 基于元素进行操作的工具方法 |
| 47 | + */ |
| 48 | + private Elements elementUtils; |
| 49 | + /** |
| 50 | + * 代码创建器 |
| 51 | + */ |
| 52 | + private Filer fileCreator; |
| 53 | + /** |
| 54 | + * 日志消息输出器 |
| 55 | + */ |
| 56 | + private Messager messager; |
| 57 | +
|
| 58 | + @Override |
| 59 | + public synchronized void init(ProcessingEnvironment processingEnvironment) { |
| 60 | + super.init(processingEnvironment); |
| 61 | + elementUtils = processingEnv.getElementUtils(); |
| 62 | + fileCreator = processingEnv.getFiler(); |
| 63 | + messager = processingEnv.getMessager(); |
| 64 | + } |
| 65 | +... |
| 66 | +``` |
| 67 | +5. 实现**process**抽象方法(return true则代表处理了注解),方法中的参数**RoundEnvironment**可以通过**getElementsAnnotatedWith**方法获取到被注解修饰的元素 |
| 68 | + |
| 69 | +### [详细处理](http://www.jianshu.com/p/50d95fbf635c) |
0 commit comments