构建 Android 库时出错:不支持直接本地 .aar 文件依赖项
Posted
技术标签:
【中文标题】构建 Android 库时出错:不支持直接本地 .aar 文件依赖项【英文标题】:Error building Android library: Direct local .aar file dependencies are not supported 【发布时间】:2020-07-07 18:07:43 【问题描述】:我们最近升级到了 android Gradle 插件 4.0.0-beta03。我们现在在构建我们的库模块之一时看到此错误
$ ./gradlew library_module: 组装 任务 ':library_module:bundleDebugAar' 执行失败。 > 构建 AAR 时不支持直接本地 .aar 文件依赖项。 生成的 AAR 将被破坏,因为来自任何本地 .aar 的类和 Android 资源 文件依赖项不会打包在生成的 AAR 中。以前版本的 Android 在这种情况下,Gradle 插件也会产生损坏的 AAR(尽管没有抛出此错误)。这 以下 :library_module 项目的直接本地 .aar 文件依赖项导致此错误: ______.aar我可以看到这是几个月前的added to AGP。但他们没有提供有关原因的更多信息。
所以。
-
出了什么问题?还有更多信息吗?我在任何地方都找不到一个错误报告。
我该如何解决这个问题?这是否是说我不能建立一个依赖于其他本地 .aar 的 .aar?如果这个本地 aar 托管在 Maven Central 或另一个远程仓库上怎么办?为什么会有不同?
【问题讨论】:
@spollom@google.com 对此有何评论? 【参考方案1】:我最近遇到了同样的问题,解决方法是从libs/
中删除库并使用File -> New -> New Module -> Import .JAR/.AAR Package
导入它,然后在库模块build.gradle
文件中引用它:
dependencies
implementation project(":imported_aar_module")
如果您使用的是较新的 Android Studio 版本 (4.0.0+),则此选项不可用。相反,您必须手动完成。
-
新建一个目录,将以下内容放入新目录下的
build.gradle
文件中:
configurations.maybeCreate("default")
artifacts.add("default", file('[nameOfTheAar].aar'))
-
将
aar
放入这个新目录。在build.gradle
文件旁边。
将新创建的 Gradle 项目添加到 settings.gradle
文件中:
include(":pathToTheCreatedDirectory")
-
将项目包含在您要使用
aar
的库中:
implementation project(":pathToTheCreatedDirectory", configuration = "default")
【讨论】:
有了这个解决方案,我们会突然需要更多的模块。很遗憾没有关于这个新警告的更多信息,这对我来说并不合乎逻辑,我们的项目是这样工作的。 好像没有人在制作 gradle 时考虑过这种情况 只是一个提醒意见 - 我正在寻找一种解决方案,其中一个 AAR 可以包含另一个 AAR。这个答案并非如此。第二个 AAR 已成功创建,但未与第一个绑定。 导入 .JAR/.AAR 包在 android studio 4 中不可用。 @Sabrina 在这种情况下,您必须手动完成。签出此github issue 作为初学者。【参考方案2】:在构建依赖于其他 Android 库(即aar
文件)的 Android 库时,如果将 aar 文件作为依赖项包含在项目中,则会收到以下错误消息:
构建 AAR 时不支持直接本地 .aar 文件依赖项。生成的 AAR 将被破坏,因为来自任何本地 .aar 文件依赖项的类和 Android 资源不会打包在生成的 AAR 中。在这种情况下,早期版本的 Android Gradle 插件也会产生损坏的 AAR(尽管没有抛出此错误)。
如上述消息所述,当您构建 Android 库项目时,它所依赖的任何 aar 都不会被打包。如果您在 AGP(Android Gradle 插件)4 之前以这种方式构建,您可能注意到您必须在使用您的库的项目中包含 aar 依赖项。
您可以通过指定 aar 依赖项为 compileOnly
来编译您的 Android 库项目。有关何时使用compileOnly
的更多信息,请参阅this。
所以只需将以下内容添加到您的 app
build.gradle
文件中:
compileOnly files('libs/some-library.aar')
请注意,如果您这样做,则必须在使用您的库的应用程序项目中包含 aar 依赖项。
或者,您可以创建一个模块,将您的 aar
依赖项导入为上述答案中提到的 @Sandi。
另一种方法是将您的 aar
依赖项发布到 maven 存储库,然后将它们添加到您的库项目中,如下所示:
implementation 'mylibrarygroup:mylibraryartifact:version-x.y.z@aar'
【讨论】:
您的回答对我很有帮助。谢谢。 不确定这个答案如何帮助任何人。谷歌声明:“你不能将 compileOnly 配置与 AAR 依赖项一起使用。”在他们的文档中:developer.android.com/studio/build/dependencies @DarkNeuron 那是因为 OP 的用例不同:你有一个库项目,它编译成一个也依赖于其他 aars 的 aar。因此,对于这种情况,compileOnly 适用于我的回答中提到的警告(即,您必须包含仅在使用库的项目中编译的 aar 依赖项) 什么?不不,我的用例完全一样:正在构建一个使用 AAR 的库。我发布了上述内容,因为它不起作用。一切都已编译,但最终捆绑包中缺少该库。这让我很困惑,直到我看到谷歌的那条笔记。无论如何,我通过提取其中包含的 jar 文件解决了我的 aar 问题。这可能并不适合所有人。 @Żabojad 那么您不理解上述答案。您必须包含依赖项。【参考方案3】:我想提一下@StefMa 对这个问题的评论,它非常简单,为我解决了这个问题,但它被隐藏在这个线程的许多其他 cmets 中,很容易被忽略。
此线程上的“正确”答案不再有效,因为无法再如该答案中所述在 Android Studio 中导入 AAR。但是,StefMa 的评论中提到的链接到this GitHub post 的解决方案确实有效,而且效果很好。
长话短说 - 将您的 AAR 放入一个单独的模块中。
无需费力地创建 lib 目录,只需按照以下说明操作即可 -
-
在项目的根目录中创建一个新目录。下图显示了其中两个 -
spotify-app-remote
和 spotify-auth
,但一个就足够了。在其中,放入您的 AAR,并创建一个新的 build.gradle
文件。
-
在
build.gradle
文件中,添加以下内容,将 aar 文件名替换为您的 AAR 文件的名称 -
configurations.maybeCreate("default")
artifacts.add("default", file('spotify-app-remote-release-0.7.1.aar'))
-
将此添加到您的
settings.gradle
文件中,替换为您创建的目录的名称
include ':spotify-app-remote'
-
在您希望使用 AAR 的模块中包含您的新模块。例如,如果您想在
app
模块中使用它,请打开应用程序的 build.gradle
并添加
api project(':spotify-app-remote')
在您的 dependencies
块内,显然再次将 spotify-app-remote 替换为您的模块名称。
【讨论】:
完美运行。谢谢 这应该是 2021 年及以后公认的答案。必须手动执行此操作真的很愚蠢。所以有些事情告诉我,Android Studio 的开发人员并没有傻到这样离开它,所以可能在 Android Studio 的下一个版本中,我们都会回到这里,试图找出另一种方法。 是否可以通过添加多个artifacts.add
子句将多个 AAR 添加到单个 library module
?【参考方案4】:
现在有一些变化,您需要将 AAR 或 JAR 添加为 依赖项
1.) 首先,导航到 文件 > 项目结构 [参考图1]
2.) 然后转到 Dependencies > Declared Dependencies 选项卡,点击并在下拉菜单中选择 JAR/AAR Dependency [参考图2]
3.)在“添加 Jar/Aar 依赖项”对话框中,首先输入 .aar 或 .jar 文件的路径,然后选择应用依赖项的配置。如果该库应可用于所有配置,请选择“实施”配置。 [参考图3]
4.) 点击OK,然后点击Apply > OK。
你可以走了。
【讨论】:
有效!但文件结构与 Sandi 的答案不同。【参考方案5】:根据我的经验,当 Gradle 插件版本为 4.2.2+ 且 Gradle 版本为 7.1+ 时,@Luis 的回答“compileOnly”有效。
compileOnly files('libs/your_library_name.aar')
Gradle 版本较低时它不起作用。
【讨论】:
有了这个它可以编译,但后来在应用程序中当我尝试调用这个库时它会崩溃 @murt 你有崩溃的日志吗? 是的,它确实可以编译,但是 aar 不会在运行时加载并且应用程序崩溃。 是的,这只是答案的一半。 @Luis 回答添加重要的补充; “请注意,如果您这样做,您将必须在使用您的库的应用程序项目中包含 aar 依赖项。”有关如何做到这一点,请参阅 Simon 的答案。【参考方案6】:我遇到了同样的问题,因为我想将库依赖项封装到模块中。然而,这个库依赖有一堆 aars 并且创建单独的模块每个都是混乱的,甚至无法在新工作室中找到该选项。
为了解决这个问题,我在开始构建过程之前将 aar-s 发布到了我的本地 maven 中。
所以我的封装模块的 build.gradle 看起来像这样:
plugins
id 'com.android.library'
id 'kotlin-android'
id 'maven-publish'
//..
parent.allprojects // for some reason simply repositories didn't work
repositories
mavenLocal()
//...
publishing
publications
barOne(MavenPublication)
groupId 'foo-aar-dependency'
artifactId 'bar1'
version '1.0'
artifact("$libsDirName/bar1.aar")
barTwo(MavenPublication)
groupId 'foo-aar-dependency'
artifactId 'bar2'
version '1.0'
artifact("$libsDirName/bar2.aar")
barThree(MavenPublication)
groupId 'foo-aar-dependency'
artifactId 'bar3'
version '1.0'
artifact("$libsDirName/bar3.aar")
// and so on...
// add the publication before the build even starts
// used ./gradlew mymodule:assemble --dry-run to find where to put it
afterEvaluate
tasks.clean.dependsOn("publishToMavenLocal")
tasks.preBuild.dependsOn("publishToMavenLocal")
dependencies
implementation "foo-aar-dependency:bar1:1.0"
implementation "foo-aar-dependency:bar2:1.0"
implementation "foo-aar-dependency:bar3:1.0"
// and so on
// also I had to make sure to add the aar's transitive dependencies as implementation below
注意:当我第一次同步时,找不到依赖项,但只要调用任何 clean/assemble,依赖项就会在之前发布,因此它会根据需要运行。
注意 2:其中大部分可以移动到一个单独的文件中,以免你的 build.gradle 混乱
注意 3:如果您真的想将模块作为库发布,则此解决方案不适合您。
注意 4:如果您运行 clean 然后下一个任务,这也适用于 CI。
【讨论】:
【参考方案7】:这是Android Studio 4.0.+中的bug。。不过,有解决办法。
首先,project/build.gradle:
allprojects
repositories
google()
jcenter()
mavenCentral()
flatDir dirs "../MoudleA/aars,../MoudleB/aars,../MoudleC/libs".split(",")
二、Moudle/build.gradle:
// MoudleA/build.gradle
repositories
flatDir
dirs 'aars'
dependencies
api fileTree(dir: 'libs', include: ['*.jar'])
//api fileTree(dir: 'aars', include: ['*.aar'])
// aar
new File('MoudleA/aars').traverse(
nameFilter: ~/.*\.aar/
) file ->
def name = file.getName().replace('.aar', '')
api(name: name, ext: 'aar')
// MoudleB/build.gradle
repositories
flatDir
dirs 'aars'
dependencies
api fileTree(dir: 'libs', include: ['*.jar'])
//fullApi fileTree(dir: 'aars/full', include: ['*.aar'])
//liteApi fileTree(dir: 'aars/lite', include: ['*.aar'])
// aar
new File('MoudleB/aars/full').traverse(
nameFilter: ~/.*\.aar/
) file ->
def name = file.getName().replace('.aar', '')
fullApi(name: 'full/' + name, ext: 'aar')
new File('MoudleB/aars/lite').traverse(
nameFilter: ~/.*\.aar/
) file ->
def name = file.getName().replace('.aar', '')
liteApi(name: 'lite/' + name, ext: 'aar')
// MoudleC/build.gradle
repositories
flatDir
dirs 'libs'
dependencies
//api fileTree(dir: 'libs', include: ['*.jar','*.aar'])
api fileTree(dir: 'libs', include: ['*.jar'])
// aar
new File('MoudleC/libs').traverse(
nameFilter: ~/.*\.aar/
) file ->
def name = file.getName().replace('.aar', '')
api(name: name, ext: 'aar')
对我有用,你也可以试试。
【讨论】:
【参考方案8】:使用此代码时遇到相同的错误。
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.aar'], dir: 'libs')
用以下代码替换您的代码。
打开顶层“build.gradle”文件并添加。
repositories
flatDir
dirs('/src/main/libs')
然后在您项目的 build.gradle 中添加以下内容。
api(name:'aar_module_name', ext:'aar')
【讨论】:
【参考方案9】:您可以将 AAR 上传到 Artifactory,然后使用它们。
【讨论】:
【参考方案10】:如果您想在您的库中捆绑本地 .aar
并在另一个项目中使用该库,您可以查看“fat aars”https://github.com/kezong/fat-aar-android
【讨论】:
【参考方案11】:编辑:如果 AAR 不包含 android 资源或本机代码,这可以帮助您。
如果您希望将此本地资源直接链接到“app”或“sdk”模块 (不编译)
=> 使用罐子。
将 .aar 重命名为 .zip 解压 使用里面的classes.jar就是这样。
【讨论】:
jars 不等同于 aar,它们不能包含本机代码或其他 android 资源。 当然。但如果不是这种情况,这个技巧可能会很有用。【参考方案12】:在 build.gradle.kts 文件中执行此操作的更懒惰的方法是使用 fileTree
和 flatDir
存储库。
repositories
flatDir
dir("$rootDir/libraries")
dependencies
fileTree("$rootDir/libraries").forEach file ->
implementation(group = "", name = file.name.removeSuffix(".aar"), ext = "aar")
这样,当您将 deps 添加或删除到文件夹时,它们会自动配置
【讨论】:
【参考方案13】:就我而言,我意识到我在错误的位置创建了 libs 文件夹,然后在 main
文件夹中重新创建了文件夹,implementation fileTree(include: ['*.aar'], dir: 'libs')
工作正常。
【讨论】:
【参考方案14】:使aar依赖适应maven repo标准并依赖它。
让我们连接build.gradle
中的依赖
repositories
maven url "$project.projectDir/libs"
dependencies
api "my-library-group:my-library-module:my-library-version"
用下一个文件替换你的 libs/myLibrary.arr
文件:
libs/my-library-group/my-library-module/my-library-version/my-library-module-my-library-version.aar
libs/my-library-group/my-library-module/my-library-version/my-library-module-my-library-version.pom
libs/my-library-group/my-library-module/maven-metadata-local.xml
其中my-library-module-my-library-version.aar
是原始aar文件
my-library-module-my-library-version.pom
的内容
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>my-library-group</groupId>
<artifactId>my-library-module</artifactId>
<version>my-library-version</version>
<packaging>aar</packaging>
</project>
maven-metadata-local.xml
的内容
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>my-library-group</groupId>
<artifactId>my-library-module</artifactId>
<versioning>
<latest>my-library-version</latest>
<release>my-library-version</release>
<versions>
<version>my-library-version</version>
</versions>
<lastUpdated>20211130111015</lastUpdated>
</versioning>
</metadata>
请随意将my-library-group
、my-library-module
、my-library-version
替换为您喜欢的任何值
【讨论】:
【参考方案15】:当我将我的 Android 插件版本增加到 4.0.1 时,我也遇到了这个问题,它变成了错误,尝试了一些解决方案,但在我们的项目中实际上没有一个是可行的。
由于我们使用的是产品风格,而不同的风格使用不同的本地 aar 文件,我们根本不能只使用 api(name: "xxx", ext: 'aar')
,因为这些 aar 文件位于不同的 flatDir
中。
现在我必须回滚到以前的 gradle 插件版本。
如果我弄清楚了,我会编辑这个答案
【讨论】:
【参考方案16】:对我来说这个解决方案有效: 将此字符串放入 build.gradle:app 文件中的依赖项:
api fileTree(dir: 'libs', include: ['*.aar'])
【讨论】:
以上是关于构建 Android 库时出错:不支持直接本地 .aar 文件依赖项的主要内容,如果未能解决你的问题,请参考以下文章
安卓工作室 4.4.2。构建 AAR 时不支持直接本地 .aar 文件依赖项
Android,不使用支持库时,DrawerLayout 的等效类是啥?
不使用 Android 支持库时的 NavUtils 等价物?
android 应用程序中的 Geckoview 因错误“java.lang.Exception:加载 sqlite 库时出错”而崩溃