importcom.google.auto.service.AutoService;importcom.squareup.javapoet.ClassName;importcom.squareup.javapoet.JavaFile;importcom.squareup.javapoet.MethodSpec;importcom.squareup.javapoet.TypeName;importcom.squareup.javapoet.TypeSpec;importjava.io.IOException;importjava.util.HashMap;importjava.util.HashSet;importjava.util.Locale;importjava.util.Map;importjava.util.Set;importjavax.annotation.processing.AbstractProcessor;importjavax.annotation.processing.ProcessingEnvironment;importjavax.annotation.processing.Processor;importjavax.annotation.processing.RoundEnvironment;importjavax.annotation.processing.SupportedSourceVersion;importjavax.lang.model.SourceVersion;importjavax.lang.model.element.Element;importjavax.lang.model.element.Modifier;importjavax.lang.model.element.TypeElement;importjavax.lang.model.util.Elements;/*** author: rexkell
* explain:*/@AutoService(Processor.class)
@SupportedSourceVersion(SourceVersion.RELEASE_7)public class BindProcess extendsAbstractProcessor {privateElements mElementsUtil;private Map>mBindViewElems;
@Overridepublic synchronized voidinit(ProcessingEnvironment processingEnv) {super.init(processingEnv);
mElementsUtil=processingEnv.getElementUtils();
mBindViewElems=new HashMap<>();
}
@Overridepublic SetgetSupportedAnnotationTypes() {//添加需要解析的自定义注解类
Set types=new HashSet<>();
types.add(BindView.class.getCanonicalName());
types.add(BindLayout.class.getCanonicalName());returntypes;
}
@Overridepublic boolean process(Set extends TypeElement>annotations, RoundEnvironment roundEnv) {
System.out.println("Process start!");
initBindElems(roundEnv.getElementsAnnotatedWith(BindView.class));
generateJavaClass();
System.out.println("Process finish!");return true;
}//初始化绑定的控件
private void initBindElems(Set extends Element>bindElems){for(Element bindElem : bindElems){
TypeElement enclosedElem=(TypeElement) bindElem.getEnclosingElement();
Set elems=mBindViewElems.get(enclosedElem);if (elems==null){
elems=new HashSet<>();
mBindViewElems.put(enclosedElem,elems);
System.out.println(enclosedElem.getSimpleName());
}
elems.add(bindElem);
System.out.println("Add bind elem "+bindElem.getSimpleName());
}
}private voidgenerateJavaClass(){//生成Bind+ClassName+.class 文件,文件内容实现findViewById
for(TypeElement enclosedElem: mBindViewElems.keySet()){
MethodSpec.Builder methodSpesBuilder= MethodSpec.methodBuilder("bindView")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(ClassName.get(enclosedElem.asType()),"activity")
.returns(TypeName.VOID);
BindLayout bindLayoutAnno=enclosedElem.getAnnotation(BindLayout.class);if (bindLayoutAnno!=null){
methodSpesBuilder.addStatement(String.format(Locale.US,"activity.setContentView(%d)",bindLayoutAnno.value()));
}for(Element bindElem : mBindViewElems.get(enclosedElem)){
methodSpesBuilder.addStatement(String.format(Locale.US,"activity.%s=(%s)activity.findViewById(%d)",
bindElem.getSimpleName(),bindElem.asType(),bindElem.getAnnotation(BindView.class).value()));
}
TypeSpec typeSpec=TypeSpec.classBuilder("Bind"+enclosedElem.getSimpleName())
.superclass(TypeName.get(enclosedElem.asType()))
.addModifiers(Modifier.FINAL,Modifier.PUBLIC)
.addMethod(methodSpesBuilder.build())
.build();
JavaFile file=JavaFile.builder(getPackageName(enclosedElem),typeSpec).build();try{
file.writeTo(processingEnv.getFiler());
}catch(IOException e) {
e.printStackTrace();
}
}
}privateString getPackageName(TypeElement typeElement){returnmElementsUtil.getPackageOf(typeElement).getQualifiedName().toString();
}
}