Arouter适配AGP 7.3.0版本

1,856 阅读5分钟

如何调试arouter 源码

arouter的代码 主要分为 3个部分,一个是基础的arouter-api包, 然后是注解处理器arouter-compile包 最后是arouter-register 这个包, 简单概述一下 这3个模块的具体作用吧

arouter-api: 99%的人使用arouter代码 都是直接用这个包下面的api,大部分用下注解就可以了 arouter-compiler: 这里是注解处理器,目前arouter代码 依旧是只能支持kapt,还不支持ksp,有兴趣的可以自己弄一个moudle 做一下ksp的支持

arouter-regsiter: 在项目中 他的project名是 arouter-gradle-plugin ,这个包里面的代码主要作用就是在编译期间 对字节码进行插桩, 作用就是生成arouter的路由表,这个是最关键的一步,如果你不使用这个register的插桩技术, arouter也能运行,只不过此时arouter 需要在应用首次启动的时候 扫描dex文件 去生成路由表,大概耗时在1s左右

搞清楚arouter的机制 我们就要想办法调试代码了, 最简单的调试方法就是 将我们修改后的arouter 代码发布到本地mavenLocal上, 然后让项目引用我们修改后的jar包就可以了。

可以打开as的gradle task 面板,找到installLocal 这个任务 执行即可,版本号和maven名称的修改在各个子module的 gradle.propertis 中

androidx 的支持

考虑到现在support实在是太老,而且 将arouter代码 改成androidx以后,接入arouter的业务方可以少一些 Jetifier的步骤,对编译时间是有正向作用的,所以趁着这个机会,我们首先可以将arouter的代码 整体改成 支持androidx的

第一步 当然是在as工程中右键直接对项目进行androidx的转换了,这一步 不过多叙述了,大家都会

第二步, 既然我们现在是支持androidx,那么显然 arouter-compiler的包 是需要修改的,为什么? 因为这个注解处理器 以前处理的是support包啊,现在你要支持androidx 是不是 要改一下?

这一步 其实也不难了,稍微看下代码 就可以找到 Consts这个类中的常量,我们修改一下从support包 改成 androidx 即可

image.png

另外就是不要忘记了 对arouter-api的build文件修改,在以前arouter的代码中,对api这个module 对compiler的依赖是 写的1.5.2的maven 远程仓库依赖, 现在我们修改了代码以后 自然不能用这个依赖了, 改成我们本地工程依赖即可,这一步很重要,否则你api用的是以前的support,注解处理器处理成androidx的 会报很多奇怪的错

image.png

第三步 注解处理器支持androix以后,我们的asm 字节码生成部分 也要跟随修改了,其实和compiler的修改比较类似,就是支持下androidx的包即可

image.png

基本上改完这三步,你的arouter就能完美支持androix了

agp 7.3

首先要说明的是 本身agp7.3.0的代码就有bug,因为agp7.3.0 默认携带的r8 处理器对 阿里的 fastjson 处理有bug 具体表现在这个类: com.alibaba.fastjson.serializer.ASMSerializerFactory

有兴趣的可以看下issue

这里不得不吐槽,r8的bug 是真得多,大家升级agp以及 kotlin版本的时候一定要小心,动辄编译失败,或者编译成功 运行失败的。

为了避免我们在适配agp7.3的时候 引发一些不必要的故障 我们可以 将agp版本从7.3.0 改成7.3.1 即可。

然后我们看下 arouter 到底是因为什么原因导致的 在agp>7.3.0 运行失败的

首先我们可以看下报错信息:

image.png

这里很明显的 可以看出来 是我们的transfrom 出现了问题, 再重新编译一下,加入--stacktrace 命令看下具体是哪里出的错?

image.png

image.png

看这个堆栈 ,很明显是asm的api报了个错,这里再仔细想想看,asm的api 报错 只有两种可能,第一我们asm的使用方式不对,但想一想 之前agp7.3 以下都没报错,那这里还报错,只可能是是另外一个原因:

asm读取的文件发生了错误,有了这个思路就简单多了,我们简单对比一下,在agp7.2 和agp 7.3 版本中 读取的文件在哪里发生了变化

我们可以在读取的地方 加一下日志,然后对比一下变化:

先看720 运行正常的版本: image.png

再看730 报错的版本:

image.png

这已经能看出来明显的区别了,720版本中 读取jar文件 中的文件时,我们只能读取到.class 文件 而730中 我们 还读取到了 文件夹的路径 这样明显就不对了,拿文件夹路径去给asm读取 肯定会报错啊。

找到问题原因以后,修改起来就很容易了, 无非就是在asm读取文件的地方判断一下, 如果不是.class 结尾的 那就不要去读取修改他了

修改点如下:

image.png

image.png

arouter 还有什么需要适配的

经过上面一系列的修改,我们已经可以将arouter 在7.3.0上完美运行了, 那后续其实arouter还是有继续修改的必要,例如 目前arouter 仅支持kapt 而不支持ksp,这个就有点尴尬,因为ksp 的运行速度 远高于kapt,且目前jetpack的 组件已经全部支持ksp了,如果这里arouter 还不支持ksp,整体编译速度还是会有不少影响,

所以ksp 支持至关重要

另外就是transfrom的适配支持,目前agp 版本已经到了7.3.1 我们在build的时候 会发现一个告警:

API 'android.registerTransform' is obsolete. It will be removed in version 8.0 of the Android Gradle plugin.

也就是说这个API 在 8.0的时候 会被删掉,到时候 arouter 又会报错了,所以这个api也要尽早适配

可以关注下 魔改arouter 这个项目,目前已经适配了7.3.0,ksp以及transfrom 的适配也在计划中