专栏首页每天学点Android知识从0到1实现一个Android路由(4)——多模块的APT收集路由

从0到1实现一个Android路由(4)——多模块的APT收集路由

在从0到1实现一个Android路由(3)——APT收集路由中,已经实现了在同一个module中收集路由,当引入了一个other_module时,发现并没有收集到这个信息,这是咋回事呢?以前需要怎么解决呢?这就是本篇文章的由来。

other_module模块

other_module其实很简单,就一个Activity,用@Path("/otherMoudleActivity")注解,其和app模块一样引用了compiler、annotation以及api模块。

这时在app里引入了othermodule后,进行跳转,效果如下:

从上面可以看到启动othermodule中的是成功了,但是原来启动app模块中的却失败了,这是咋回事呢?

这是因为初始化时,UrlCollectorImpl的Map只有一条"/otherModuleActivity"的记录,那app模块的信息怎么没收集到呢?

这是因为每个module都会有一个PathProcessor,而PathProcessor没有考虑对多module的区分,后面的module收集到的信息就会覆盖前面的module,这就是为什么只能看到other_module的信息。

解决多module的APT收集路由

知道了原因之后,就好解决了。解决方案可以是区分每个module,给每个module生成自己的map,然后init()方法中把每个module对应类的map组合到一起,就可以了。

区分多module

参考添加注解处理器,在othermodule中加入参数标识modulename,修改build.gradle如下:

android {    defaultConfig {        javaCompileOptions {            annotationProcessorOptions {                arguments = ["module_name":"OtherModule"]            }        }    }}

可以看到添加了一个module_name的key,value为OtherModule。

修改PathProcessor

得到外部传入的参数

可以在init()方法中通过ProcessEnvironment.getOptions()获取到外部设置的参数,取出其中的设置的value,代码如下:

private static final String MODULE_NAME_KEY = "module_name";    private Filer filer;    private String classNameSuffix;    @Override    public synchronized void init(ProcessingEnvironment processingEnvironment) {        super.init(processingEnvironment);        filer = processingEnv.getFiler();        Map<String, String> options = processingEnvironment.getOptions();        for (String key : options.keySet()) {            if (key.equals(MODULE_NAME_KEY)) {                classNameSuffix = options.get(key);                break;            }        }        if (classNameSuffix == null) {            classNameSuffix = "App";        }    }

process()根据不同Module生成不同实现类

process()的实现逻辑很简单,在UrlCollectorImpl的前面加上classNameSuffix即可。

执行assembleDebug后,可以在app模块下发现AppUrlCollectorImpl,在other_module模块下发现OtherModuleUrlCollectorImpl。 APT为每个module生成的类位于每个module自己的build目录下。

整合多个UrlCollector

当生成了多个UrlCollector后,那么剩下的问题就是将这些UrlCollector的map整合到一个大的map中,这里EasyRouter提供了可以addModule()的接口,调用addModule()将其他模块生成的加入到Map中即可。代码如下:

EasyRouter.getInstance().addModule(OtherModuleUrlCollectorImpl())

这样的话,就可以实现跨模块的跳转了。

总结

APT收集路由时需要注意每个module都会有一个Processor,因此需要进行区分,而区分是通过给java编译器增加参数来进行区分的,每个module生成了各自的路由表后,还需要进行表的整合,这样才能实现最终的跨模块跳转。

关于代码,可以参考[github地址]:https://github.com/wangli135/EasyRouter/tree/7b684ca7c4c3e680351895b444a62007b78e443d(https://github.com/wangli135/EasyRouter/tree/7b684ca7c4c3e680351895b444a62007b78e443d)

参考

  • 添加注解处理器
  • AnnotationProcessorOptions

本文分享自微信公众号 - 每天学点Android知识(android_every_day),作者:星风coder

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • android WebView拦截请求详解

    WebView的基本用法相信大多数android开发者都是会使用的,最简单的就是调用个loadUrl方法,但是记得要在清单文件中添加网络权限。我也简单了写了一个...

    用户1108631
  • 深入理解OkHttp源码(三)——网络操作

    在深入理解OkHttp源码(一)——提交请求中,分析了同步、异步请求是如何经过Dispatcher到getResponseWithInterceptorChai...

    用户1108631
  • 闲话元注解@Retention

    元注解是用来描述注解的。@Retention用来描述注解将会在哪个层次存在,有三个值:

    用户1108631
  • Android设计 - 图标设计概述(Iconography)

    2014-10-30 张云飞VIR 翻译自:https://developer.android.com/design/style/iconography.htm...

    zhangyunfeiVir
  • 生成文件的另一种思路——共享文件同步

    背景 由于网站访问量大,需要多台服务器生成静态文件,然后多机负载,所有生成成了头等大事,一是方式所需,二是生成环节消耗CPU与内存操作太大,经常出问题。常用的生...

    Java中文社群_老王
  • git笔记之cherry-pick的使用

    获取某一个分支的单笔提交,并作为一个新的提交引入到你当前分支上。 当我们需要在本地合入其他分支的提交时,如果我们不想对整个分支进行合并,而是只想将某一次提交合...

    薛定喵君
  • PKW: namedtuple 和 pathlib 简介(第 5 期)

    通过工厂函数 collections.namedtuple,可以构造出带有字段名的元组,即为具名元组。 namedtuple 是元组的升级版本,通过 named...

    周萝卜
  • NYOJ 92 图像有用区域(bfs+预处理)

           这道题的意思就是在这个地图里,如果一些正数没有被0包围住就把这些正数改成0,而被0围起来的正数不变,然后输出这个地图,这就是一道bfs题,只是需要...

    Ch_Zaqdt
  • pyhton-----break语句

    Python break语句,就像在C语言中,打破了最小封闭for或while循环。break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完...

    昱良
  • 看一次Youtube,有多少AI算法为你服务?

    如此多的用户、活动和内容产生了大量的数据,因此YouTube可以充分利用AI来帮助运营。

    昱良

扫码关注云+社区

领取腾讯云代金券