Android 说说注解到编译时生成代码

开发环境: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都可以生成代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值