1、AOP:
1.1、基本介绍:
- 如果说,OOP是把问题划分到单个模块的话,那么AOP就是把涉及到众多模块的某一类问题进行统一管理。
- Android AOP就是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,提高开发效率。
1.2、应用场景:
- 日志记录:业务埋点
- 持久化
- 性能监控:性能日志
- 数据校验:方法的参数校验
- 缓存:内存缓存和持久缓存
- 权限检查:业务权限(如登陆,或用户等级)、系统权限(如拍照定位)
- 异常处理
- …
2、APT
2.1、基本介绍:
- 按照处理时期,注解分为两种类型:一种是运行时注解,另一种是编译时注解。运行时注解由于性能问题被一些人所诟病。编译时注解的核心依赖APT(Annotation Processing Tools)实现。
- APT的基本原理是在某些代码元素上(如类型、函数、字段等)添加注解,在编译时编译器会检查AbstractProcessor的子类,并且调用该类的process函数,然后将添加了注解的所有元素都传递到process函数中,使得开发人员可以在编译器进行相应的处理,例如,根据注解生成新的Java类,这也就是ARouter、 ButterKnife 、Dagger2等开源库的基本原理。
- 代表框架:DataBinding、Dagger2、ButterKnife、EventBus3 、AndroidAnnotation、ARouter。
- APT是在程序编译阶段工作。
- 注解处理器 Java5 中叫APT(Annotation Processing Tool),在Java6开始,规范化为 Pluggable Annotation Processing。
- 生成的源代码在build/generated/source/apt下可以看到。
2.2、APT的优难点:
优点:
- 它可以做任何你不想做的繁杂的工作,它可以帮你写任何你不想重复代码,将重复代码抽取出来,用AOP思想去编写。
- 它可以生成任何java代码供你在任何地方使用。
难点:
- 在于设计模式和解耦思想的灵活应用。
- 在于代理类代码生成的繁琐:你可以手动进行字符串拼接,也可以用squareup公司的javapoet库来构建出任何你想要的java代码。
3、编写APT项目的一般流程:
3.1、项目大概结构如下:
3.2、注解相关模块:
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
int value();
}
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface OnClick {
int[] value();
}
3.3、注解处理器模块:
3.3.1、基本介绍:
- 继承自AbstractProcessor抽象类去自定义注解处理器类。
- 重写AbstractProcessor以下4个方法。
void init(ProcessingEnvironment processingEnv):
• 在 这里可以初始化拿到一些实用的工具类。
Set<String> getSupportedAnnotationTypes():
• 指定这个注解处理器APT是注册给哪个注解的。
• 它的返回值是一个字符串的集合,包含本处理器想要处理的注解类型的合法全称。
SourceVersion getSupportedSourceVersion() :
• 用来指定你使用的Java版本。
boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv):【process( )可能会多次调用】
• 收集信息:
就是根据你的注解声明,拿到对应的Element,然后获取到我们所需要的信息,这个信息肯定是为了后面生成JavaFileObject所准备的。
• 生成代理类(编译时生成的类):
手动进行字符串拼接。
用javapoet第三方库进行书写。
• 返回true表示结束处理流程。
3.3.2、注册注解处理器到javac中:
3.3.2.1、基本介绍:
- 首先我们需要将我们的注解处理器打包到一个jar文件中。
- 其次在这个jar中,需要打包一个特定的文件javax.annotation.processing.Processor到META-INF/services路径下。
- 打包进jar文件中的javax.annotation.processing.Processor的内容是:所有自定义注解处理器类的合法全名列表,每一个自定义注解处理器全名用换行分割。
- javac会自动检查和读取javax.annotation.processing.Processor中的内容,并且注册自定义注解处理器作为注解处理器。
- 可以用谷歌的auto-service库完成这些操作。
3.3.2.2、auto-service使用步骤:
- 在具体的自定义注解处理器类上用注解@AutoService(Processor.class)修饰这个处理器类即可。
@AutoService(Processor.class)
public class ViewFinderProcessor extends AbstractProcessor {
...
}
3.3.3、annotationProcessor插件:
- 该插件用于处理注解处理器。
- 能在编译时期去依赖注解处理器并进行工作,但在生成 APK