当前位置:网站首页>ARouter使用自定义注解处理器,自动生成跳转Activity的代码,避免手动填写和管理path
ARouter使用自定义注解处理器,自动生成跳转Activity的代码,避免手动填写和管理path
2022-08-10 18:39:00 【guangdeshishe】
大家都知道ARouter要跳转目标Activity需要两步:
1.在Activity上添加Route
注解
// Add annotations on pages that support routing (required)
// The path here needs to pay attention to need at least two levels : /xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
2.执行ARouter.getInstance().build("/test/activity").navigation()
方法即可实现跳转
// 1. Simple jump within application (Jump via URL in 'Advanced usage')
ARouter.getInstance().build("/test/activity").navigation();
// 2. Jump with param bundle
ARouter.getInstance().build("/test/1")
.withBundle("key1", bundle)
.navigation();
这就导致了我们需要去管理大量的path字符串,为什么ARouter不能在编译时期帮我们生成一个中间类去管理这些path字符串呢?
既然官方不支持那就自己来做一个吧,整体思路如下:
1.定义两个Activity并添加Route
注解
@Route(path = "/login/LoginActivity")
class LoginActivity : AppCompatActivity() {
@Route(path = "/login/RegisterActivity")
class RegisterActivity :BaseActivity() {
2.通过自定义注解处理器,处理所有带Route
注解的类,并取出注解里的path
变量值,生成一个中间类用于管理所有的path
,并封装跳转的方法,生成的中间类如下:
package com.agilezhu.processor.generate;
import android.os.Bundle;
import java.lang.String;
public final class ARouterPage {
LoginActivity LoginActivity;
RegisterActivity RegisterActivity;
public ARouterPage() {
LoginActivity.path = "/login/LoginActivity";
RegisterActivity.path = "/login/RegisterActivity";
}
public static class LoginActivity {
public static String path;
static {
path= "/login/LoginActivity";
}
public static void navigation(String key, Bundle params) {
com.alibaba.android.arouter.launcher.ARouter.getInstance().build(path).withBundle(key,params).navigation();
}
public static void navigation() {
com.alibaba.android.arouter.launcher.ARouter.getInstance().build(path).navigation();
}
}
public static class RegisterActivity {
public static String path;
static {
path= "/login/RegisterActivity";
}
public static void navigation(String key, Bundle params) {
com.alibaba.android.arouter.launcher.ARouter.getInstance().build(path).withBundle(key,params).navigation();
}
public static void navigation() {
com.alibaba.android.arouter.launcher.ARouter.getInstance().build(path).navigation();
}
}
}
3.使用方法
//不带参数
ARouterPage.LoginActivity.navigation()
//带Bundle类型参数
ARouterPage.RegisterActivity.navigation("params",Bundle())
//也可以使用原有ARouter跳转方式携带各种参数
ARouter.getInstance().build(ARouterPage.LoginActivity.path).withBoolean("key",true).navigation();
有了注解处理器相当于自动帮我们生成了一个管理所有path的类:
- 可以通过类似调用目标Activity的方式进行跳转;
- 简化了ARouter跳转Acticity的代码;
- 每次添加、修改、删除对应的类,都不需要手动修改管理类代码;
注解处理器开发过程
添加一个java 类型Module
build.gradle
内容如下:plugins { id 'java-library' } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'//auto-service本身也是个注解处理器 implementation 'com.google.auto.service:auto-service:1.0-rc7'//注解 processor 类,并对其生成 META-INF 的配置信息 implementation 'com.squareup:javapoet:1.13.0' //通过类调用的形式来生成java代码,避免手动拼接字符串 implementation "com.alibaba:arouter-annotation:1.0.6" } java { sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 }
注解处理器核心类:
package com.agilezhu.processor; import com.alibaba.android.arouter.facade.annotation.Route; import com.google.auto.service.AutoService; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeSpec; import java.util.LinkedHashSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.tools.Diagnostic; /** * Generate ARouterPage.java for ARouter */ @AutoService(Processor.class) public class ARouterProcessor extends AbstractProcessor { private Filer mFiler; //文件相关工具类:用于保存生成的java类文件 private Elements mElementUtils; //元素相关工具类:用于获取java类文件 private Messager mMessager;//用于打印日志 @Override public synchronized void init(ProcessingEnvironment processingEnvironment) { super.init(processingEnvironment); mFiler = processingEnv.getFiler(); mElementUtils = processingEnv.getElementUtils(); mMessager = processingEnv.getMessager(); } @Override public Set<String> getSupportedAnnotationTypes() { //返回该注解处理器能够处理哪些注解 Set<String> types = new LinkedHashSet<>(); types.add(Route.class.getName()); return types; } @Override public SourceVersion getSupportedSourceVersion() { //返回当前注解处理器支持的java版本号 return SourceVersion.latest(); } @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) { if (set == null || set.size() == 0) { return false; } //将要生成的java完整类名 String targetClassName = "ARouterPage"; String packageName = "com.agilezhu.processor.generate"; //创建方法(构造方法) MethodSpec.Builder bindMethodBuilder = MethodSpec.methodBuilder("<init>") .addModifiers(Modifier.PUBLIC); //创建类 TypeSpec.Builder aRouterPageClassBuilder = TypeSpec.classBuilder(targetClassName) .addModifiers(Modifier.PUBLIC, Modifier.FINAL); //获取所有的源码文件 Set<? extends Element> elements = roundEnvironment.getRootElements(); for (Element element : elements) { if (!(element instanceof TypeElement)) { //判断是否class类 continue; } //转换成class类型 TypeElement typeElement = (TypeElement) element; //当前文件的类名 String classSimpleName = element.getSimpleName().toString(); Route routeAnnotation = element.getAnnotation(Route.class); if (routeAnnotation == null) { continue; } mMessager.printMessage(Diagnostic.Kind.WARNING, "myProcess=====>>>>>" + classSimpleName); ClassName innerClassName = ClassName.get(packageName, targetClassName, classSimpleName); try { aRouterPageClassBuilder.addField(innerClassName, classSimpleName) .addType(TypeSpec.classBuilder(innerClassName.simpleName()) .addModifiers(Modifier.STATIC, Modifier.PUBLIC) .addField(String.class, "path", Modifier.PUBLIC, Modifier.STATIC) .addStaticBlock(CodeBlock.builder().addStatement("path= \"" + routeAnnotation.path() + "\"").build()) .addMethod(MethodSpec .methodBuilder("navigation") .addParameter(String.class,"key") .addParameter(ClassName.get("android.os","Bundle"), "params") .addStatement("com.alibaba.android.arouter.launcher.ARouter.getInstance().build(path).withBundle(key,params).navigation()") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .build()) .addMethod(MethodSpec .methodBuilder("navigation") .addStatement("com.alibaba.android.arouter.launcher.ARouter.getInstance().build(path).navigation()") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .build()) .build()); } catch (Exception e) { e.printStackTrace(); } //构造方法中添加初始化代码 bindMethodBuilder.addStatement(classSimpleName + ".path = \"" + routeAnnotation.path() + "\""); } aRouterPageClassBuilder.addMethod(bindMethodBuilder.build()); //创建java文件 JavaFile bindProxyFile = JavaFile .builder(packageName, aRouterPageClassBuilder.build()) .build(); try { //保存java类文件 bindProxyFile.writeTo(mFiler); } catch (Throwable e) { e.printStackTrace(); } return false; } }
业务模块中引用:
kapt project(path: ':lib:processor') //这里用的kapt处理Kotlin代码
重新编译后,在当前模块
build/generated/source/kapt/debug/com/agilezhu/processor/generate/ARouterPage.java
路径下就能看到生成的类
边栏推荐
猜你喜欢
Optimization is a habit The starting point is to 'stand close to the critical'
状态压缩dp蒙德里安的梦想
开发模式对测试的影响
三星Galaxy Watch5产品图片流出 非Pro表款亦有蓝宝石加持
Redis命令---key篇 (超全)
120Hz OLED拒绝“烧屏”!华硕无双全能轻薄本
Keras deep learning combat (17) - image segmentation using U-Net architecture
CSV(Comma-Separate-Values)逗号分隔值文件
AIRIOT答疑第8期|AIRIOT的金字塔服务体系是如何搞定客户的?
redis.exceptions.DataError: Invalid input of type: ‘dict‘. Convert to a byte, string or number first
随机推荐
800. 数组元素的目标和(双指针)
FPGA:生成固化文件(将代码固化到板子上面)
新建离线同步节点时选择数据去向-表时报错,数据库类型是adb pg,怎么办?
弘玑Cyclone与风变科技达成战略合作:优势互补聚焦数字化人才培养
LeetCode·26.删除有序数组中的重复项·双指针
QoS服务质量七交换机拥塞管理
【FAQ】OpenHarmony与HarmonyOS的有什么区别?
多种深度模型实现手写字母MNIST的识别(CNN,RNN,DNN,逻辑回归,CRNN,LSTM/Bi-LSTM,GRU/Bi-GRU)
Three schemes of SQL query across the table
Keras深度学习实战(17)——使用U-Net架构进行图像分割
JVM内存和垃圾回收-11.执行引擎
JVM基本结构
小分子PEG CAS:1352814-07-3生物素-PEG6-丙酸叔丁酯
799. 最长连续不重复(双指针)
CAS:190598-55-1_Biotin sulfo-N-hydroxysuccinimide ester生物素化试
FPGA工程师面试试题集锦91~100
dumpsys meminfo 详解
面试题 04.12. 求和路径-dfs+辅助数组法
剑指 Offer 27. 二叉树的镜像(翻转二叉树)
幕维三维动画——港珠澳大桥沉管安装三维动画实况