阅读本文前请先了解Android Apt(Annotation Processing Tool)。
基于Apt的Android路由框架请参考
PageRouter 一款轻量级Android路由框架(支持Activity与Fragment跳转)。
春节后上班第一天将项目的gradle版本由4.10.1升级至5.0,升级完成后编译失败...
RouterInitializer是路由框架通过apt在编译期间自动生成的类,作用是往路由表里添加路由条目,如果你了解apt的话应该知道RouterInitializer中的代码由你写的Processor实现类生成。
可是我只是升级了下gradle版本,为什么RouterInitializer就无法生成了呢?查看下gradle的升级文档,Upgrading your build from Gradle 4.x to 5.0 ,没发现什么有用信息....
正常情况下打出来的jar包结构是这样的
要了解这个services目录是干什么的,需要了解Java的SPI机制。 SPI 全称为 (Service Provider Interface) 服务提供者接口,是JDK内置的一种服务提供发现机制。SPI是一种动态替换发现的机制, 用于接口或抽象类运行时动态的给它添加实现。
Android APT各种教程中,配置build.gradle要引入google开源的auto-service,然后在Process实现类上添加@AutoService(Processor.class)注解,这个auto-service其实就是帮我们生成META-INF/services/下配置文件的。当服务的提供者提供了一种接口的实现之后,需要在classpath下的META-INF/services/目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候,就可以通过查找这个jar包(一般都是以jar包做依赖)的META-INF/services/中的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名进行加载实例化,就可以使用该服务了。JDK中查找服务实现的工具类是:java.util.ServiceLoader。
到这里我就差不多明白了,升级gradle后auto-service并没有生成SPI所必须的META-INF/services/配置文件,具体为什么auto-service会失效,原因暂不明确,但解决方案就比较清晰了,既然你不帮我生成对应的接口配置文件,我就自己配置一个呗,毕竟自己动手丰衣足食....
根目录下创建resources/META-INF/services目录,services中创建以接口的全路径名命名的文件javax.annotation.processing.Processor,然后在该文件的第一行,把Processor接口实现类的全路径名写上,搞定...
再试一下,果然可以了,这样auto-service就不需要了移除即可。