ARouter源码解析(四)

前言

之前对 arouter-api 做了整个流程的分析,今天来看看 arouter-compiler 。

arouter-compiler 主要是利用 apt 在编译期自动生成代码的。之前我们看到的 ARouter$$Root$$appARouter$$Group$$testTest1Activity$$ARouter$$Autowired 等都是 arouter-compiler 生成的。

那接下来就分析分析 arouter-compiler 是怎么生成这些源码的。

arouter-compiler

arouter-compiler 中 processor 有三种:

  • AutowiredProcessor : 用来生成像 Test1Activity$$ARouter$$Autowired 这种类型;
  • InterceptorProcessor : 用来生成像 ARouter$$Interceptors$$app 这种类型;
  • RouteProcessor : 用来生成像 ARouter$$Root$$appARouter$$Providers$$appARouter$$Group$$test 这种类型;

RouteProcessor

在这里我们就只分析 RouteProcessor 了。

RouteProcessor 相比其他两个 Processor 来说,代码更长,逻辑更加复杂。并且 RouteProcessor 主要处理的是路由映射这一块。其他两个 RouteProcessor 也是大同小异,有兴趣的同学可以自行阅读源码。

先来看看 RouteProcessor 的定义:

@AutoService(Processor.class)
@SupportedOptions({KEY_MODULE_NAME, KEY_GENERATE_DOC_NAME})
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes({ANNOTATION_TYPE_ROUTE, ANNOTATION_TYPE_AUTOWIRED})
public class RouteProcessor extends AbstractProcessor {
    ...
}

RouteProcessor 类上面的注解很多,我们一个一个来看:

  • @AutoService 会自动在 META-INF 文件夹下生成 Processor 配置信息文件,避免手动配置的麻烦;
  • @SupportedOptions 指定 Processor 支持的选项参数名称,KEY_MODULE_NAME 就是 AROUTER_MODULE_NAME ,KEY_GENERATE_DOC_NAME 就是 AROUTER_GENERATE_DOC;没错,这两个就是我们一开始在 build.gradle 中配置的。
  • @SupportedSourceVersion 指定 Processor 支持的 JDK 的版本;
  • @SupportedAnnotationTypes 指定 Processor 处理的注解;

接着,趁热打铁。来瞧瞧 RouteProcessor 的 init 方法。

@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
    super.init(processingEnv);

    mFiler = processingEnv.getFiler();                  // Generate class.
    types = processingEnv.getTypeUtils();            // Get type utils.
    elements = processingEnv.getElementUtils();      // Get class meta.

    typeUtils = new TypeUtils(types, elements);
    logger = new Logger(processingEnv.getMessager());   // Package the log utils.

    // Attempt to get user configuration [moduleName]
    Map<String, String> options = processingEnv.getOptions();
    if (MapUtils.isNotEmpty(options)) {
        moduleName = options.get(KEY_MODULE_NAME);
        generateDoc = VALUE_ENABLE.equals(options.get(KEY_GENERATE_DOC_NAME));
    }

    if (StringUtils.isNotEmpty(moduleName)) {
        moduleName = moduleName.replaceAll("[^0-9a-zA-Z_]+", "");

        logger.info("The user has configuration the module name, it was [" + moduleName + "]");
    } else {
        logger.error(NO_MODULE_NAME_TIPS);
        throw new RuntimeException("ARouter::Compiler >>> No module name, for more information, look at gradle log.");
    }

    // 如果需要生成路由 doc
    if (generateDoc) {
        try {
            docWriter = mFiler.createResource(
                    StandardLocation.SOURCE_OUTPUT,
                    PACKAGE_OF_GENERATE_DOCS,
                    "arouter-map-of-" + moduleName + ".json"
            ).openWriter();
        } catch (IOException e) {
            logger.error("Create doc writer failed, because " + e.getMessage());
        }
    }

    iProvider = elements.getTypeElement(Consts.IPROVIDER).asType();

    logger.info(">>> RouteProcessor init. <<<");
}

在 init 方法中,主要获取了 KEY_MODULE_NAME 和 KEY_GENERATE_DOC_NAME 这两个编译选项参数。然后判断一下是否需要生成路由文档。

在 init 方法中获取参数后,接着就是 process 方法。

process 方法就好像是 main 方法一样,在这里面都是 processer 处理注解自动生成代

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值