1、生成类的Processor必须在类型为“Java or Kotlin Library"的module下,如果没有,则需要新建一个[原因是需要引入
[javax.annotation.processing]包,这个包是jre下面的,只有在这种类型的Module下才能引入。
2、实现
AbstractProcessor的方法,代码示例如下:
@AutoService(Processor.class)
public class HandlerProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
//注解处理器提供的API
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "HandlerProcessor init");
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> hashSet = new HashSet<>();
hashSet.add(Handler.class.getCanonicalName());
return hashSet;
}
/**
* 编译版本,固定写法就可以
*/
@Override
public SourceVersion getSupportedSourceVersion() {
return processingEnv.getSourceVersion();
}
/**
* 扫描注解回调
*/
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
//拿到所有添加Handler注解的成员变量
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Handler.class);
if(elements.size() == 0 ) {
return false;
}
Element firstEle = elements.stream().findAny().get();
Handler firstHandler = firstEle.getAnnotation(Handler.class);
String packageName = firstHandler.pakcageName();
String pakcage = "com.nhzero.connection.handler";
String simpleClsName = "ConnectionHandlerRegister";
String className = "com.nhzero.connection.handler.ConnectionHandlerRegister";
if(packageName.contains("device")) {
className = "com.nhzero.device.handler.DeviceHandlerRegister";
pakcage = "com.nhzero.device.handler";
simpleClsName = "DeviceHandlerRegister";
}
try {
JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(className);
Writer writer = fileObject.openWriter();
writer.write("package " + pakcage + ";\n");
writer.write("import com.nhzero.connection.HandlerContext;\n");
writer.write("import com.nhzero.connection.handler.MessageHandler;\n");
for (Element element : elements) {
Name simpleName = element.getSimpleName();
Handler handler = element.getAnnotation(Handler.class);
writer.write("import " + handler.pakcageName() + "." + simpleName + ";\n");
}
writer.write("public class " + simpleClsName + " {\n");
writer.write(" public static void init() {\n");
int i = 0;
for (Element element : elements) {
//拿到成员变量名
Name simpleName = element.getSimpleName();
Handler handler = element.getAnnotation(Handler.class);
//输出成员变量名
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, simpleName);
if(handler.hasGetInstance()) {
writer.write(" MessageHandler handler" + i + " = " + simpleName + ".getInstance();\n");
} else {
writer.write(" MessageHandler handler" + i + " = new " + simpleName + "();\n");
}
writer.write(" HandlerContext.addHandler(handler" + i + ", MessageHandler.class, " +
(handler.isMultiple()? "e -> e.supportTypes())": "e -> e.supportType())") + ";\n");
i++;
}
writer.write(" }\n");
writer.write("}\n");
writer.flush();
writer.close();
} catch (Exception e) {
}
return false;
}
}
3、上述生成类的HandlerProcessor 所在的module的gradle文件
plugins {
id 'java-library'
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
compileOnly 'com.google.auto.service:auto-service:1.0-rc6'
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'
}
//java控制台输出中文乱码
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
4、其他module引入上述module
implementation project(':base:apt')
annotationProcessor project(path: ':base:apt')
annotationProcessor 是用于注解扫描,
implementation 是用于引入上面module中定义的Handler注解,这个例子是把注解类和Processor类放在了同一个module下面。
5、特别要注意的
module引入annotationProcessor project(path: ':base:apt') 只能扫描当前module下的加注解的类,而不能扫描引入的其他jar包或其他module下带注解的类