本章主要讲解组件化是如何实现组建之间参数传递的,代码基于之前一章内容架构师学习–组件化开发之路由ARouter设计
一、如何实现模块之间参数的传递
1、通过getIntent()传统方式
2、通过javapoet
最终生成的文件格式如下:
二、代码生成
1、创建参数注解
2、创建注解处理器
(1)遍历Parameters节点
(2)解析Parameters节点,并保存到map
map集合key为当前activity。value为Parameters节点集合。
(3)构建ARouter$$Parameters文件
private void createFile() throws IOException {
if (EmptyUtils.isEmpty(mListMap)) return;
// 通过Element工具类,获取Parameter类型
TypeElement activityElement = elementUtils.getTypeElement(Constant.ACTIVITY);
TypeElement paramsElement = elementUtils.getTypeElement(Constant.PARAMETER_PATH);
//构建传递的参数
ParameterSpec parameterSpec = ParameterSpec.builder(TypeName.OBJECT,
Constant.PARAMETER_NAME).build();
//拿到注解
Set<Map.Entry<TypeElement, List<Element>>> entries = mListMap.entrySet();
for (Map.Entry<TypeElement, List<Element>> entry : entries) {
TypeElement element = entry.getKey();
//判断当前注解是否作用在activity之上
if (!typeUtils.isSubtype(element.asType(), activityElement.asType())) {
throw new RuntimeException("@Parameter注解目前仅限用于Activity类之上");
}
//获取类名
ClassName className = ClassName.get(element);
//方法体内容构建
ParameterFactory parameterFactory =
new ParameterFactory
.Builder(parameterSpec)
.setClassName(className)
.setMessager(mMessager)
.build();
//添加方法体第一行内容 MainActivity activity = ((MainActivity)obj);
parameterFactory.addFirstStatement();
//遍历类中所有的属性
for (Element childElement : entry.getValue()) {
//添加参数
parameterFactory.buildStatement(childElement);
}
//最终生成的文件名称
String finalClassName = element.getSimpleName() + Constant.PARAMETER_FILE_NAME;
mMessager.printMessage(Diagnostic.Kind.NOTE, "当前生成的类名:" + finalClassName);
//构建生成文件 ,记住要和当前activity在同一级目录
JavaFile
.builder(className.packageName(), //包名
TypeSpec.classBuilder(finalClassName) //类名
.addModifiers(Modifier.PUBLIC) //访问修饰符
.addSuperinterface(ClassName.get(paramsElement)) //继承接口
.addMethod(parameterFactory.build()) //方法
.build()) //TypeSpec构建
.build() //JavaFile 构建
.writeTo(mFiler); // 文件生成器开始生成类文件
}
}
注意点:由于我们最终使用t.xx = t.getIntent().getxxxExtras(xxx);形式,所以生成的文件必须要和注解所在的类在同级目录下,这样才能访问类的属性。
(4)方法构建操作交给ParameterFactory完成
比如:方法中的第一步强转,代码如下:
后面就是循环获取参数,如果没有用户没有设置keyName,将会根据字段名称作为key。
完成以上集成,编译代码,会在对应注解类的目录下生成处理器文件。
(5)使用,在注解的activity中调用如下代码:
new Main_MainActivity$$Parameter().loadParams(this);