package cn.jack.annotation_compiler;
import com.google.auto.service.AutoService;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
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.SupportedOptions;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject;
import cn.jack.annotation.BindPath;
//https://github.com/google/auto/tree/master/service
//Apt不可以在编译时修改东西 但是ASM(待手写demo)可以
@AutoService(Processor.class) //添加了该注解,javac就知晓
@SupportedOptions("moduleName")//AMS 2.注解处理器加上注解,表示接收哪个值 需要跟gradle中配置的相同
public class AnnotationCompiler extends AbstractProcessor {
//这个方法的返回值是一个Set集合,集合中指要处理的注解类型的名称(这里必须是完整的包名+类名,例如com.example.annotation.BindView)。由于在本例中只需要处理@BindView注解,因此Set集合中只需要添加@BindView的名称即可。
//2.能用来处理哪些注解
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new HashSet<>();
types.add(BindPath.class.getCanonicalName());
return types;
}
//这个方法非常简单,只有一个返回值,用来指定当前正在使用的Java版本,通常return SourceVersion.latestSupported()即可。
//1.支持的版本
@Override
public SourceVersion getSupportedSourceVersion() {
//1.1.processingEnv:是父类中的变量
return processingEnv.getSourceVersion();
}
//3.定义一个用来生成APT目录下面的文件的对象
private Filer filer;
//这个方法用于初始化处理器,方法中有一个ProcessingEnvironment类型的参数,ProcessingEnvironment是一个注解处理工具的集合。它包含了众多工具类。
//例如:
//Filer可以用来编写新文件;
//Messager可以用来打印错误信息;
//Elements是一个可以处理Element的工具类。
//重点:不同类型Element其实就是映射了Java中不同的类元素
String moduleName;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
filer = processingEnv.getFiler();
//AMS 3.得到moduleName
Map<String, String> options = processingEnv.getOptions();
moduleName = options.get("moduleName");
System.out.println("moduleName " + moduleName);
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (!annotations.isEmpty()) {
//获得被注解的类集合
Set<? extends Element> routeElements = roundEnv.getElementsAnnotatedWith(BindPath.class);
generatedClass(routeElements);
return true;
}
return false;
}
private void generatedClass(Set<? extends Element> routeElements) {
StringBuilder sb = new StringBuilder();
sb.append("package cn.jack.arouters;\n"); //优化:跟各个模块的包名相同 不可以 暂时写死 在transform中需要扫描
sb.append("import android.app.Activity;\n");
sb.append("import cn.jack.arouter.IRouter;\n");
sb.append("import java.util.Map;\n");
for (Element element : routeElements) {
TypeElement typeElement = (TypeElement) element;
sb.append("import ");
sb.append(typeElement.getQualifiedName());
sb.append(";\n");
}
//类
sb.append("public class ");
sb.append(moduleName);
sb.append("Router implements IRouter{\n");
sb.append("@Override\n");
sb.append("public void putActivity(Map<String, Class<? extends Activity>> routes){\n");
for (Element element : routeElements) {
//获得注解
BindPath route = element.getAnnotation(BindPath.class);
//函数体 paths.put(xx,xx.class)
sb.append("routes.put(\"");
sb.append(route.value());
sb.append("\",");
sb.append(element.getSimpleName());
sb.append(".class);\n");
}
sb.append("}\n");
sb.append("}");
try {
//创建 Java文件
JavaFileObject sourceFile = filer.createSourceFile("cn.jack.arouters." + moduleName +
"Router");
//输出字符串
OutputStream outputStream = sourceFile.openOutputStream();
outputStream.write(sb.toString().getBytes());
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//注释该部分,重新使用AMS的方式实现
//4.最重要的一个方法
//在这个方法的方法体中,我们可以校验被注解的对象是否合法、可以编写处理注解的代码,以及自动生成需要的java文件等
//我们要处理的大部分逻辑都是在这个方法中完成
//TypeElement介绍:各种Element代表Java的哪些部分
// @Override
// public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
// //在javac编译的时候回调该方法
// //补充:这个方法执行了3次(具体原因不清楚)
//
// //4.2.获取APP中所有用到了BindPath注解的对象
// //找到经过BindPath注解修饰的类,得到一堆Element
// Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(BindPath.class);
//
// //重复一下:不同类型Element其实就是映射了Java中不同的类元素
// //PackageElement 表示一个包程序元素。提供对有关包及其成员的信息的访问。
// //TypeElement 类 表示一个类或接口程序元素。提供对有关类型及其成员的信息的访问。注意,枚举类型是一种类,而注解类型是一种接口。
// //VariableElement 属性 表示一个字段、enum 常量、方法或构造方法参数、局部变量或异常参数。
// //ExecutableElement 方法 表示某个类或接口的方法、构造方法或初始化程序(静态或实例),包括注释类型元素。
//
// //4.3.开始对elementsAnnotatedWith进行分类
//
// //4.3.1.容器
// Map<String, String> map = new HashMap<>();
//
// //4.3.2.扫描所有被@BindPath注解的元素 遍历节点
// for (Element element : elements) {
// //我们知晓BindPath注解的作用域,故可以强制类型转换
// TypeElement typeElement = (TypeElement) element; //TypeElement:表示的是类
// String activityName = typeElement.getQualifiedName().toString();//得到类名
// String key = typeElement.getAnnotation(BindPath.class).value(); //拿到类上的注解
// map.put(key, activityName + ".class");
// }
//
// //4.3.3.开始生成文件
// if (map.size() > 0) {
// //写文件,需要借助Filer工具
// //生成工具类,工具
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
PracticeArouter.zip (88个子文件)
PracticeArouter
gradlew.bat 3KB
gradlew 6KB
gradle.properties 1KB
Arouter
proguard-rules.pro 770B
src
test
java
cn
jack
arouter
ExampleUnitTest.java 392B
androidTest
java
cn
jack
arouter
ExampleInstrumentedTest.java 774B
main
java
cn
jack
arouter
IRouter.java 186B
ARouter.java 3KB
AndroidManifest.xml 155B
consumer-rules.pro 0B
.gitignore 6B
build.gradle 1KB
libs
buildSrc
src
main
resources
META-INF
gradle-plugins
cn.jack.buildsrc.properties 47B
java
cn
jack
buildsrc
RegisterCodeGenerator.java 5KB
CoustomTransform.java 7KB
AsmPlugin.java 770B
AsmTransform.java 9KB
JavassistPlugin.java 770B
build.gradle 582B
annotation
src
main
java
cn
jack
annotation
BindPath.java 314B
.gitignore 6B
build.gradle 143B
libs
annotation_compiler
src
main
java
cn
jack
annotation_compiler
AnnotationCompiler.java 10KB
.gitignore 6B
build.gradle 369B
libs
app
proguard-rules.pro 750B
src
test
java
cn
jack
practicearouter
ExampleUnitTest.java 384B
androidTest
java
cn
jack
practicearouter
ExampleInstrumentedTest.java 760B
main
res
mipmap-xxxhdpi
ic_launcher.webp 4KB
ic_launcher_round.webp 8KB
drawable
ic_launcher_background.xml 5KB
mipmap-hdpi
ic_launcher.webp 1KB
ic_launcher_round.webp 3KB
drawable-v24
ic_launcher_foreground.xml 2KB
values
colors.xml 378B
themes.xml 817B
strings.xml 77B
values-night
themes.xml 817B
mipmap-xxhdpi
ic_launcher.webp 3KB
ic_launcher_round.webp 6KB
mipmap-mdpi
ic_launcher.webp 982B
ic_launcher_round.webp 2KB
mipmap-xhdpi
ic_launcher.webp 2KB
ic_launcher_round.webp 4KB
mipmap-anydpi-v26
ic_launcher_round.xml 272B
ic_launcher.xml 272B
layout
activity_main.xml 731B
xml
data_extraction_rules.xml 551B
backup_rules.xml 478B
java
cn
jack
practicearouter
BaseApplication.java 283B
MainActivity.java 883B
AndroidManifest.xml 897B
.gitignore 6B
build.gradle 1KB
libs
gradle
wrapper
gradle-wrapper.jar 58KB
gradle-wrapper.properties 236B
homemoudle
proguard-rules.pro 770B
src
test
java
cn
jack
homemoudle
ExampleUnitTest.java 395B
androidTest
java
cn
jack
homemoudle
ExampleInstrumentedTest.java 775B
main
res
mipmap-xxxhdpi
ic_launcher.png 10KB
ic_launcher_round.png 16KB
drawable
ic_launcher_background.xml 6KB
mipmap-hdpi
ic_launcher.png 4KB
ic_launcher_round.png 5KB
drawable-v24
ic_launcher_foreground.xml 2KB
values
colors.xml 387B
themes.xml 852B
strings.xml 74B
values-night
themes.xml 852B
mipmap-xxhdpi
ic_launcher.png 8KB
ic_launcher_round.png 12KB
mipmap-mdpi
ic_launcher.png 3KB
ic_launcher_round.png 3KB
mipmap-xhdpi
ic_launcher.png 5KB
ic_launcher_round.png 7KB
mipmap-anydpi-v26
ic_launcher_round.xml 276B
ic_launcher.xml 276B
layout
activity_home.xml 801B
alone
AndroidManifest.xml 259B
java
cn
jack
homemoudle
HomeActivity.java 415B
AndroidManifest.xml 745B
.gitignore 6B
build.gradle 2KB
libs
.gitignore 225B
local.properties 419B
config.gradle 285B
settings.gradle 147B
build.gradle 325B
共 88 条
- 1
资源评论
慢行的骑兵
- 粉丝: 8
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- kernel-ml-6.8.8-1.el7.elrepo.x86-64.rpm
- Labview基本框架之状态机
- HM2309B-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- Git安全实践:保护你的代码仓库个人学习笔记.md
- 自动驾驶定位系列教程九:后端优化.pdf
- 三国志5威力加强版-windows
- HM2309A-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- HM2306-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- Git进阶技巧:提升团队协作效率个人学习笔记.md
- 自动驾驶定位系列教程八:建图系统结构优化.pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功