需要新建一个library,这个library引用一个aar,最后需要将这个library发布到公司的私有Maven仓库,然后项目主工程通过Maven引用这个library。目录结构如下:
demoApp | +--app(demo app module) | +--zenmkit(library module) | +--zenm-iot-sdk(aar module) | +--xxxx.aar anotherApp | +--app | +--zenmkit(from Maven)
1. 普通方式,将aar放在zenmkit的libs目录中,implementation fileTree(dir: “libs”, include: [“*.jar”, “*.aar”])编译时,提示
Direct local .aar file dependencies are not supported when building an AAR. The resulting AAR would be broken because the classes and Android resources from any local .aar file dependencies would not be packaged in the resulting AAR. Previous versions of the Android Gradle Plugin produce broken AARs in this case too (despite not throwing this error). The following direct local .aar file dependencies of the :zenmkit project caused this error: /Users/wuzongheng/DEV/luckin/code/LKM/zenmkit-android/zenmkit/libs/zenm-iot-sdk-release-2.0.8.aar
故该方法无效
2. demoApp中通过 File->New->New Module->Import .JAR/.AAR Package 的方式新建一个引入了aar的module叫zenm-iot-kit,zenmkit引用这个module: implementation project(“:zenm-iot-sdk”) 或者直接把aar复制到zenmkit的libs文件夹中再通过 api(name: ‘zenm-iot-sdk-release-2.0.8’, ext: ‘aar’) 引入aarhttps://stackoverflow.com/a/60888941/5671750demoApp可以正常使用,可以正常编译上传至Maven,将库传到Maven中后,anotherApp引入后编译时,提示 找不到xxxxx.aar
Execution failed for task ':app:preDebugBuild'. > Could not resolve all files for configuration ':app:debugCompileClasspath'. > Could not find ZenmKit:zenm-iot-sdk:unspecified. Required by: project :app > com.luckin:lkzenmkit:0.1.0-SNAPSHOT:20201111.021559-1 Possible solution: - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
anotherApp再用demoApp中一样的方式创建一个aar的module,并依赖后,无法解决。直接将aar放入libs的方式也无法解决。查询发现是因为用implementation引入zenmkit的话会在pom中加入依赖,从而anotherApp引入时,会检查依赖,而此时会找不到对这个aar或者zenm-iot-kit的module的依赖。在zenmkit中用provided或者compileOnly引入aar的话不写入pom,所以anotherApp使用时只会在运行时再检测能不能加载到依赖的类,于是尝试3
3. demoApp中新建一个module叫zenm-iot-kit,在这个module中引入aar,zenmki引用这个module: compileOnly project(“:zenm-iot-sdk”)https://stackoverflow.com/a/27171938/5671750demoApp可以正常使用,可以正常编译上传至Maven,将库传到Maven中后,anotherApp引入成功,但是运行时,提示
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/zenmeasure/iot/sdk/sdk_manager/ZenmSDKManager;
此时必然是因为我们传到Maven的aar只包含我们的代码,不包含原始引入的aar的类,于是在anotherApp中再用demoApp中一样的方式创建一个zenm-iot-kit,并依赖后,发现竟然无法解决
4. demoApp中直接将aar放在zenmkit的libs文件夹中,provided files(‘libs/zenm-iot-sdk-release-2.0.8.aar’)https://blog.csdn.net/spring0832/article/details/107985803demoApp运行时提示
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/zenmeasure/iot/sdk/sdk_manager/ZenmSDKManager;
再在demoApp中新建一个module叫zenm-iot-kit,在这个module中引入aar,demoApp中的app依赖它,demo可以正常运行但是上传至Maven后,anotherApp使用这个库时,依然提示这个错误,并且无法使用demoApp一样的方式解决
5. 使用能将aar与zenmkit合并merge打包成一个aar的fat-aar插件,在zenmkit中通过 embed(name: ‘zenm-iot-sdk-release-2.0.8’, ext: ‘aar’) 或者通过 embed project(“:zenm-iot-sdk”) 的方式,将aar文件中的类都打包进我们的zenmkithttps://github.com/kezong/fat-aar-android/blob/master/README_CN.md生成的aar确实既包含了zenmkit中的代码,也包含了aar文件中的类,但是最终anotherApp从Maven中引入最终aar后,也还是找不到类,而且Dilutions的注解,无法在编译阶段解析,从而在zenmkit中定义的路由无法调用
6. 使用另一个fat-aarhttps://github.com/cpdroid/fat-aar生成的aar,在anotherApp中编译的时候报错
7. 把6中的fat-aar工具将aar编译成的jar嵌入anotherApp,运行的时候还是找不到类。此时就很诡异了,因为这个jar再普通不过了,竟然单纯的引入jar都无法加载jar中的类
将编译出来的apk直接放在AS中查看各个classes.dex,发现确实没有要加载的类,开始思考是否在编译阶段出问题,仔细查看编译阶段的日志输出,发现在 do aspectj real work 阶段有抛出空指针,
trouble in: public class a.a.d.b extends a.a.d.c:
而这个类正是引入的aar文件中的类,但是没有中断掉编译过程,于是在aspectjx的配置中把出问题a.a这个类路径exclude掉,之后就正常了
结论:
1. 要二次打包aar,最佳实践是在library project中通过File->New->New Module->Import .JAR/.AAR Package 的方式新建一个引入了aar的module,再在library module中通过compileOnly project(“:zenm-iot-sdk”)的方式只在编一阶段引入aar而不写入pom。之后主工程在Maven方式引入aar后,需要同时引入library module所依赖的那个aar文件,因为library module打出来的aar不包含所依赖的aar的类
2. 如果要一次性将aar中的类全部打包进library module打出来的aar中,需要借助fat-aar插件,github上有很多实现,需要注意每个插件支持的gradle和gradle plugin版本号
3. 即使在充满各种可能性,信息量庞大的情况下,也要保持对任何日志中的报错信息的敏感度