最近本着不求甚解的态度重温了一下主流框架的源码,所以趁热打铁的总结一下,学习框架或开发框架所必备的基础知识:
1、简介
在我们常用的框架中注解和自动生成代码的身影很常见,因为注解和自动生成的配合,从而简化和统一代码,使框架使用简单且容易扩展,典型且最熟悉的就是ButterKnife,主要功能利用注解省略了findViewById的过程,当然也提供了其他的监听、绑定等很多强大的操作符,熟悉ButterKnife源码的应该知道,ButterKnife的实现就是利用我们今天的要讲的内容,我们在文章的最后也会尝试编写一个简单的ButterKnife;
2、构建
2.1、创建Java Library
在Android项目中创建Java Library
2.2、配置build.gradle 文件
implementation 'com.squareup:javapoet:1.11.1'
implementation 'com.google.auto.service:auto-service:1.0-rc4'
2.3、创建AbstractProcessor的子类
代码的自动生成使用的是AbstractProcessor类,所以第一步要添加AbstractProcessor的实现类
@AutoService(Processor.class)
public class MYProcessor extends AbstractProcessor {
private Filer mFiler;
private Elements mElements;
private Messager mMessage;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
mFiler = processingEnv.getFiler();
mElements = processingEnv.getElementUtils();
mMessage = processingEnv.getMessager();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
MethodSpec methodSpec = MethodSpec.methodBuilder("processMethod") // 添加方法
.addModifiers(Modifier.PUBLIC) // 添加方法修饰符
.addParameter(String.class, "name") // 添加方法参数
.build();
TypeSpec typeSpec = TypeSpec.classBuilder("ProcessCreate") // 设置要生成的类
.addModifiers(Modifier.PUBLIC) // 添加类修饰符
.addMethod(methodSpec) // 将方法添加类中
.build();
JavaFile javaFile = JavaFile.builder("com.example.administrator.permission", typeSpec).build(); //设置JavaFile
try {
javaFile.writeTo(mFiler); // 写入
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new LinkedHashSet<>();
types.add(Override.class.getCanonicalName());
return types;
}
}
上面是实现类的全部代码,作几点说明:
-
添加@AutoService(Processor.class)注解
-
主要方法介绍:
-
init(ProcessingEnvironment env): 每一个注解处理器类都必须有一个空的构造函数。然而,这里有一个特殊的init()方法,它会被注解处理工具调用,并输入ProcessingEnviroment参数。ProcessingEnviroment提供很多有用的工具类Elements,Types和Filer;
-
process(Set<? extends TypeElement> annoations, RoundEnvironment env):这相当于每个处理器的主函数main()。在这里写扫描、评估和处理注解的代码,