开发环境:Java 1.8,Android studio 4.0,主module是支持kotlin模块
项目结构: 项目地址github
3.注解module不用添加依赖
4.注解编译module的build代码如下:
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//生成代码的一个库,比手写方便的多,功能强大,自动导包
implementation 'com.squareup:javapoet:1.12.1'
//google的 auto service库,自动生成service,省去了手动配置resources/META-INF/services
implementation 'com.google.auto.service:auto-service-annotations:1.0-rc7'
implementation project(path: ':annotations')
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
compileOnly files ('C:/Program Files/Java/jdk1.8.0_231/jre/lib/rt.jar')//如果javax包没有,则添加此包
}
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
4.注解代码:ActivityNavigateFactory
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ActivityNavigateFactory {
String name();//显示名称
}
5.编译器代码:ANFProcessor
import com.google.auto.service.AutoService;
import com.novel.annotations.ActivityNavigateFactory;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
@AutoService(Processor.class)
@SupportedAnnotationTypes({"com.novel.annotations.ActivityNavigateFactory"})
public class ANFProcessor extends AbstractProcessor {
private final String TAG = "EBrowser ANFProcessor -> ";
private Filer mFiler;
private static final String className = "ActivitysNav";
private static final String methodName = "getActivityNavs";
private static final String packageName = "edo.liu.ebrowser.annotation";
private boolean isProcessed = false;//is finish create process
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {//maybe process one more time
if (!isProcessed) {
System.out.println(TAG + "process");
} else {
System.out.println(TAG + "processed return");
return true;
}
try {
/**
* create return classType
*/
ParameterizedTypeName returnType = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
ClassName.get(Class.class));
/**
* create method
* public static Map<String, Class> getAllNavActivitys() {
* Map<String,Class> activitys = new HashMap();
*
* $L(for Literals), $S(for Strings), $T(for Types), $N(for Names)
*/
MethodSpec.Builder methodBuild = MethodSpec.methodBuilder(methodName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addStatement("$T<$T,$T> activitys = new $T()", Map.class, String.class, Class.class, HashMap.class)
.returns(returnType);
Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ActivityNavigateFactory.class);
for (Element element : elements) {
ActivityNavigateFactory annotation = element.getAnnotation(ActivityNavigateFactory.class);
methodBuild.addStatement("activitys.put($S, $T.class)", annotation.name(), element.asType());
}
methodBuild.addStatement("return activitys");
TypeSpec typeSpec = TypeSpec.classBuilder(className)
.addModifiers(Modifier.PUBLIC)
.addJavadoc(new String("用于页面跳转".getBytes(), StandardCharsets.UTF_8))//class上面生成多行注释
.addMethod(methodBuild.build())
.build();
JavaFile javaFile = JavaFile.builder(packageName, typeSpec)
.addFileComment("this code for navigation page")//代码顶部生成注释
.build();
javaFile.writeTo(mFiler);
isProcessed = true;
System.out.println(TAG + "create ActivitysNav finish");
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "create failed");
}
return true;
}
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {//just run one time
super.init(processingEnvironment);
System.out.println(TAG + "init");
mFiler = processingEnvironment.getFiler();
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return Collections.singleton(ActivityNavigateFactory.class.getCanonicalName());
}
}
6.按照上图添加主moduled:app依赖
dependencies{
...
implementation project(path: ':annotations')
kapt project(path: ':processor') //kapt = annotationProcessor
}
7.调试:菜单栏 → build → Make project/Rebuild Project都可以生成代码