美文网首页
APT使用记录

APT使用记录

作者: 鈤汌冈板 | 来源:发表于2018-03-23 17:19 被阅读16次

新建java library 的module,创建MyRouteProcessor类并继承AbstractProcessor,具体实现如下:

@AutoService(Processor.class)
public class MyRouteProcessor extends AbstractProcessor {
    private Filer mFiler;
    private Messager mMessager;
    private Elements mElementUtils;
    private boolean mCreated = false; //记录文件是否已经创建
    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        mFiler = processingEnvironment.getFiler();
        mMessager = processingEnvironment.getMessager();
        mElementUtils = processingEnvironment.getElementUtils();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annotations = new LinkedHashSet<>();
        annotations.add(Route.class.getCanonicalName());
        return annotations;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        Set<? extends Element> RouteElements = roundEnvironment.getElementsAnnotatedWith(Route.class);
        note(String.format("RouteElements size  = %s", RouteElements.size()));
        HashMap<String, String> routeList = new HashMap<>();
        String pkgName = "";
        for (Element element : RouteElements) {
            //1.获取包名
            PackageElement packageElement = mElementUtils.getPackageOf(element);
            String pkName = packageElement.getQualifiedName().toString();
            note(String.format("package = %s", pkName));

            TypeElement classElement = (TypeElement) element;
            String className = classElement.getSimpleName().toString();
            String classFullName = classElement.asType().toString();
            note(String.format("classFullName = %s", classFullName));
            note(String.format("className = %s", className));

            //4.获取注解元数据
            Route bindView = element.getAnnotation(Route.class);
            String id = bindView.value();
            note(String.format("id = %s", id));
            routeList.put(id, classFullName);

            //写文件
            if (pkgName.equals("")) {
                pkgName = mElementUtils.getPackageOf(classElement).getQualifiedName().toString();
            }

        }
        //4.生成文件
        if (RouteElements.size() > 0) {
            createFile(routeList, pkgName);
        }
        return true;
    }

    private void createFile(HashMap<String, String> map, String pkgName) {
        try {
            String fileFullPath = pkgName + ".RouteList";
            JavaFileObject jfo = mFiler.createSourceFile(fileFullPath, new Element[]{});
            Writer writer = jfo.openWriter();
            writer.write(brewCode(map, pkgName));
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private String brewCode(HashMap<String, String> map, String pkgName) {
        StringBuilder builder = new StringBuilder();
        builder.append("package " + pkgName + ";\n\n");
        builder.append("import java.util.HashMap;\n");
        builder.append("import java.util.Map;\n\n");
        builder.append("//Auto generated by apt,do not modify!!\n\n");
        builder.append("public class RouteList { \n\n");
        builder.append("public static HashMap<String, String> mRouteMap = new HashMap<String, String>(){ \n");
        builder.append("{ \n");
        for (String key : map.keySet()) {
            builder.append("put(\"" + key + "\"" +","+"\"" + map.get(key) + "\");" + "\n");
        }
        builder.append("  }");
        builder.append("};");
        builder.append("}");
        return builder.toString();
    }
    private void note(String msg) {
        mMessager.printMessage(Diagnostic.Kind.NOTE, msg);
    }
}

创建将要使用的注解

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Route {
    String value() default "";
}

创建resource目录下创建META-INF/services/javax.annotation.processing.Processor文件,并在文件第一行注明自己定义的processor全路径

com.example.processor.MyRouteProcessor

具体目录如下


20180323171824288.png

然后在其他module中引用此module,clean并build就可以在build/generated/source/apt中看到生成的代码了

相关文章

网友评论

      本文标题:APT使用记录

      本文链接:https://www.haomeiwen.com/subject/trvxcftx.html