如何在Kotlin的build.gradle.kts中将A.aar打包进B.aar库
Android库B内嵌依赖A.aar的实现方案
核心思路
要将本地Maven仓库中的A.aar完全内嵌到B.aar中,需修改B模块的构建逻辑:将A的依赖改为本地文件依赖,并通过Gradle任务确保A.aar的内容(包括代码、资源、JNI库等)被打包进最终生成的B.aar,同时避免依赖冲突。
步骤1:获取本地Maven中的A.aar文件
根据A的Maven坐标com.example.servicelibrary:servicelibrary:1.0,找到其在本地仓库的路径,例如:
- 本地Maven路径:
~/.m2/repository/com/example/servicelibrary/servicelibrary/1.0/servicelibrary-1.0.aar - 项目本地repository路径:
项目根目录/repository/com/example/servicelibrary/servicelibrary/1.0/servicelibrary-1.0.aar
将该A.aar复制到B模块的libs目录下(若无libs则新建)。
步骤2:修改B模块的build.gradle.kts
2.1 替换依赖声明
移除原来的远程Maven依赖:
// 移除这一行 implementation("com.example.servicelibrary:servicelibrary:1.0")
替换为本地aar文件依赖:
implementation(files("libs/servicelibrary-1.0.aar")) { // 排除与B重复的传递依赖,避免打包冲突 exclude(group = "androidx.appcompat", module = "appcompat") // 按需添加其他需要排除的依赖 }
2.2 添加打包配置与内嵌任务
在android代码块中添加以下配置,确保A.aar的内容被内嵌到B.aar:
android { // ... 原有compileSdk、defaultConfig等配置保持不变 ... packagingOptions { pickFirst("**/*.aar") exclude("META-INF/*.kotlin_module") exclude("META-INF/LICENSE") // 按需排除重复的元文件 } // 遍历所有library变体,将A.aar的内容合并到B的构建产物中 libraryVariants.all { variant -> // 复制A.aar的JNI库到B的JNI目录 val copyJniLibsTask = tasks.register<Copy>("copy${variant.name.capitalize()}JniLibs") { from(zipTree("libs/servicelibrary-1.0.aar").matching { include("jni/**") }) into("$buildDir/intermediates/merged_jni_libs/${variant.name}/jni") } // 复制A.aar的资源到B的资源目录 val copyResourcesTask = tasks.register<Copy>("copy${variant.name.capitalize()}Resources") { from(zipTree("libs/servicelibrary-1.0.aar").matching { include("res/**") }) into("$buildDir/intermediates/merged_res/${variant.name}/res") } // 合并A.aar的class文件到B的classes.jar val mergeClassesTask = tasks.register<Jar>("merge${variant.name.capitalize()}Classes") { from(zipTree("libs/servicelibrary-1.0.aar").matching { include("classes.jar") }) from(variant.javaCompileProvider.get().destinationDir) archiveFileName.set("merged-classes.jar") destinationDirectory.set(file("$buildDir/intermediates/merged_classes/${variant.name}")) } // 让assemble任务依赖上述所有内嵌任务 variant.assembleProvider.configure { dependsOn(copyJniLibsTask, copyResourcesTask, mergeClassesTask) } // 替换默认的classes.jar为合并后的文件 variant.outputs.all { output -> output.packageLibraryProvider.configure { from(mergeClassesTask.get().outputs.files) } } } }
2.3 可选:自动从本地Maven拉取A.aar
若不想手动复制A.aar,可添加Gradle任务自动从本地仓库拉取:
tasks.register<Copy>("pullAarFromMaven") { // 替换为A.aar在本地Maven的实际路径 val aarSourcePath = "${System.getProperty("user.home")}/.m2/repository/com/example/servicelibrary/servicelibrary/1.0/servicelibrary-1.0.aar" from(aarSourcePath) into("libs") include("*.aar") } // 让assemble任务先执行拉取操作 tasks.withType<AbstractArchiveTask>().configureEach { dependsOn("pullAarFromMaven") }
步骤3:验证内嵌结果
执行构建命令生成B.aar:
./gradlew :moduleB:assembleRelease
生成的B.aar位于moduleB/build/outputs/aar/目录下,解压后可验证:
classes.jar包含B和A的所有class文件res/目录包含A的资源jni/目录包含A的JNI库(若有)
注意事项
- 若A.aar包含ProGuard规则,需将其合并到B的
proguard-rules.pro中 - 确保A与B的minSdk、compileSdk版本兼容
- 测试时将生成的B.aar引入空Android项目,验证所有功能正常运行
内容的提问来源于stack exchange,提问作者Srinivas Sarda
相关产品推荐
相关产品推荐

