新建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中看到生成的代码了
网友评论