美文网首页
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