meituan/WMRouter

为啥将apt生成的文件写入到assets

Closed this issue · 4 comments

您好,看到源码里面对RouterService注解的处理,是先用注解处理器生成了文件,放到了map中,然后又用了transform将map里的数据写入到了assets中,想知道您为什么要这设计。谢谢!

  1. 注解生成Java资源文件,文件名就是接口名,文件内容指向接口的实现类,多个Library工程可能会有相同接口的不同实现,所以编译期间需要把同名资源文件的内容按行合并起来,这部分和Java的ServiceLoader基本一致。

  2. 在Android中,首次加载Java资源文件的性能差,因此通过插件复制到assets中,通过读assets获取实现类。

  3. 之所以把文件内容转成map又重新生成文件,而不是直接把文件内容合并,一方面为了检查同一个接口的实现类是否配置了重复的key,另一方面是为了解决Java资源合并的问题:

    Java资源文件的合并主要由Android Gradle Plugin自己完成,直接取transformResourcesWithMergeJavaRes的输出即可。但是Android Gradle Plugin部分低版本(大概是2.3.3左右,具体不记得了)有问题,只合并了Library的资源,漏掉了主工程的资源,所以WMRouterServiceProcessor里有个getClassesDir,会取主工程的资源文件再读一遍,而这样在高版本中主工程资源就会重复,所以用map把重复的内容去掉。

gzsll commented

assets文件来自mergeAsstes任务,从3.2.0开始目录从build/intermediates/assets修改为build/intermediates/merged_assets,现在是build/intermediates/assets,高版本的gradle会有问题 @jzj1993

好的,感谢反馈~ 后续可能会判断高版本使用正确的assets目录,也在考虑直接用Transform读取注解生成初始化class,而不用注解生成器、资源文件、Assets实现效果(现在没有全用Transform是担心本地编译性能问题)。由于Transform是Android官方给出的正规API,可靠性更好,而其他实现都是用了Hack手法,升级了版本可能就不兼容了。

@gzsll 1.1.0版本已经重新实现了Gradle插件,不再使用资源文件和assets,问题已解决。