这两天在打包时碰到这个错误"Direct local .aar file dependencies are not supported when building an AAR",找到错误的原因是子module有依赖本地的arr文件行为导致打包错误,拉尼?查找了一些资料才得知原因。
为什么本地文件不行?
当你直接在 build.gradle
中声明本地 .aar
文件作为依赖时,你绕过了 Gradle 的依赖解析系统。这意味着:
- 无法解析传递性依赖 :
.aar
文件可能有它自己的依赖,而直接引用不会解析这些传递性依赖。 - 版本冲突无法解决 :如果有多个版本的同一依赖存在,Gradle 通常可以帮你解决这些冲突。直接引用
.aar
文件无法享受这一便利。 - 缺乏灵活性:直接依赖本地文件使得项目与构建环境紧密耦合,降低了项目的移植性和灵活性。
Android Gradle 插件的进化
随着 Android Gradle
插件的发展,对 AAR 的处理也在不断改进。在早期的版本中,可能没有这样的限制,但随着插件的成熟,它开始强制执行更好的依赖管理实践,这包括不允许直接依赖本地 AAR 文件。
解决问题
我这里的gradle版本是7.3.3,应该是gradle版本升级较高版本才会出现这个错误吧,好了大致明白其中缘由我们赶紧解决这个问题吧!
1.集中管理aar包
首先在根目录创建一个libs
文件夹,这里作为我们存放子module的aar包集中管理,由于我的aar包属于广告模块下需要的依赖,所以在libs文件夹内再按照模块创建一个文件夹AdLIB_aar_android
,将我的广告aar包转移到AdLIB_aar_android
文件夹,这样可以区分不同模块的aar包,然后再创建一个dependencies.gradle
脚本管理。
2.添加flatDir配置
通过添加flatDir配置才能告诉 Gradle 它们的位置,这里我们在settings.gradle
中添加, 这里写了一个getLibsSubDirs()
方法,用于获取libs 目录下的所有子目录,因为我们可能需要根据模块的不同创建不同的aar文件夹(这里是为了更好的管理),所有的文件夹都需要指向其具体的目录地址,不然的话无法添加aar。
附上代码:
js
// 在这个脚本中定义一个方法来获取 libs 目录下的所有子目录
def getLibsSubDirs() {
def dirs = []
file('libs').eachDir { dirs.add(it) }
return dirs
}
其实现在我们就可以直接添加依赖了,在需要添加aar包的模块build.gradle中dependencies
内添加引用,这里替换成你需要添加的aar包(aar包需要添加在AdLIB_aar_android
目录中,文件目录可以根据自身不同模块的需要创建)
js
implementation(name: 'Baidu_MobAds_SDK_v9.324', ext: 'aar')
implementation(name: 'GDTSDK.unionNormal.4.550.1420', ext: 'aar')
implementation(name: 'kssdk-ad-3.3.55.2', ext: 'aar')
可是一个一个的implementation
也太不优雅了吧!你觉得呢?这时候我们写的dependencies.gradle
脚本作用就来了!
3.编写dependencies.gradle脚本
js
ext {
// 这里定义了一个 Gradle 扩展属性区块。
println "dependencies.gradle is being applied"
// 当这个脚本被应用时,输出日志信息以确认其正在执行。
// 定义一个闭包,这个闭包用来将指定文件夹内的所有 AAR 文件添加为依赖。
addAarDependencies = { module, libsFolderName ->
println "addAarDependencies is called for project: ${libsFolderName}"
// 当这个闭包被调用时,打印出是那个libs 目录下相应文件夹。
// 根据传入的文件夹名,创建一个指向 libs 目录下相应文件夹的 File 对象。
def libsDir = new File(rootDir, "/libs/${libsFolderName}")
// rootDir 通常指向项目的根目录。
// 检查这个目录是否存在并且是一个目录。
if (libsDir.exists() && libsDir.isDirectory()) {
println "Directory ${libsDir} exists and is being scanned for AAR files."
// 如果条件成立,输出日志信息,表明将要扫描这个目录。
// 遍历目录内所有的 `.aar` 文件。
libsDir.eachFileMatch(~/.*\.aar/) { File aarFile ->
// eachFileMatch 方法使用正则表达式来匹配文件名。
// 获取不带扩展名的文件名。
String fileNameWithoutExtension = aarFile.name[0..aarFile.name.lastIndexOf('.')-1]
println "Adding AAR file: ${fileNameWithoutExtension}"
// 输出正在添加的 AAR 文件名。
// 实际添加依赖到模块中。这里使用 `implementation` 配置。
module.dependencies.add("implementation", [name: fileNameWithoutExtension, ext: 'aar'])
}
println "Scanning for AAR files completed."
// 扫描并添加完成后,输出日志信息。
} else {
println "Directory ${libsDir} does not exist or is not a directory."
// 如果指定的目录不存在或者不是一个目录,输出错误信息。
}
}
}
这个addAarDependencies
闭包它可以被 Gradle 构建脚本中的任何模块调用,以便将一个特定文件夹内的所有 AAR 文件动态添加为依赖。这使得管理本地库文件变得更加灵活和自动化。
我们还需要将外部的 Gradle 脚本文件应用(或包含)到当前的 Gradle 构建脚本中
在项目根目录的build.gradle
中添加apply from: 'libs/dependencies.gradle'
,这样我们才能使用。
4.添加aar依赖
这里第一个参数是需要添加aar包的模块,第二个是我们需要添加的aar包文件夹,也就是我们前面创建的,通过改变不同的aar文件夹名称就可以依赖不同的aar包,有了这个Gradle 构建脚本我们就可以很轻松的添加aar依赖了!不再需要进行多次implementation处理,只需要一句解决问题。