构建 Android 库时出错:不支持直接本地 .aar 文件依赖项

Error building Android library: Direct local .aar file dependencies are not supported

我们最近升级到 Android Gradle 插件 4.0.0-beta03。我们现在在构建我们的库模块之一时看到此错误

$ ./gradlew library_module:assemble

任务 ':library_module:bundleDebugAar' 执行失败。
> 构建 AAR 时不支持直接本地 .aar 文件依赖项。
生成的 AAR 将被破坏,因为来自任何本地 .aar 的 类 和 Android 资源
文件依赖项不会打包到生成的 AAR 中。 Android 的早期版本
Gradle 在这种情况下,插件也会产生损坏的 AAR(尽管不会抛出此错误)。这
以下 :library_module 项目的直接本地 .aar 文件依赖项导致此错误:
______.aar

我可以看到这是 added to AGP 几个月前的事了。但他们没有提供更多信息来说明原因。

所以。

  1. 问题是什么?还有更多信息吗?我在任何地方都找不到一个错误报告。
  2. 我该如何解决这个问题?这是不是说我不能构建一个依赖于其他本地 .aar 的 .aar?如果这个本地 aar 托管在 Maven Central 或另一个远程 repo 上怎么办?为什么会有不同?

我最近遇到了同样的问题,修复方法是从 libs/ 中删除库并使用 File -> New -> New Module -> Import .JAR/.AAR Package 导入它,然后在库模块 build.gradle 文件中引用它:

dependencies {
  implementation project(":imported_aar_module")
}

如果您使用的是较新的 Android Studio 版本 (4.0.0+),则此选项不可用。相反,您必须手动完成。

  1. 创建一个新目录并将以下内容放入新目录的build.gradle文件中:
configurations.maybeCreate("default")
artifacts.add("default", file('[nameOfTheAar].aar'))
  1. aar 放入这个新目录。 build.gradle 文件旁边。
  2. 将新创建的 Gradle 项目添加到 settings.gradle 文件:
include(":pathToTheCreatedDirectory")
  1. 在您要使用 aar:
  2. 的库中包含项目
implementation project(":pathToTheCreatedDirectory", configuration = "default")

当我将 Android 插件版本增加到 4.0.1 时,我也遇到了这个问题,它变成了错误,尝试了一些解决方案,但其中 none 实际上在我们的项目中是可行的。
由于我们使用的是产品口味,而不同的口味使用不同的本地 aar 文件,我们不能只使用 api(name: "xxx", ext: 'aar'),因为这些 aar 文件位于不同的 flatDir
现在我必须回滚到以前的 gradle 插件版本。
如果我想通了,会编辑这个答案

这是Android Studio 4.0.+中的错误。但是,有一个解决方案。

首先,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')
    }
}

对我有用,你也可以试试

在构建依赖于其他 Android 库(即 aar 文件)的 Android 库时,如果将 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).

正如上面的消息所述,当您构建一个 Android 库项目时,它所依赖的任何 aar 都不会被打包。如果您在 AGP(Android Gradle 插件)4 之前以这种方式构建,您可能会注意到您必须在使用您的库的项目中包含 aar 依赖项。

您可以通过指定 aar 依赖项 compileOnly 来编译您的 Android 库项目。有关何时使用 compileOnly 的更多信息,请参阅 this

所以只需将以下内容添加到您的 app build.gradle 文件中:

compileOnly files('libs/some-library.aar')

请注意,如果您这样做,您将必须在使用您的库的应用程序项目中包含 aar 依赖项。

或者,您可以创建一个模块来导入您的 aar 依赖项,如上述答案中提到的

另一种方法是将您的 aar 依赖项发布到 Maven 存储库,然后将它们添加到您的库项目中,如下所示:

implementation 'mylibrarygroup:mylibraryartifact:version-x.y.z@aar'

现在有一些变化,您需要添加 AARJAR 作为 dependency

1.) 首先,导航至 文件 > 项目结构 [参考图片 1]

2.) 然后转到 Dependencies > Declared Dependencies 选项卡,单击 select JAR/AAR Dependency在下拉列表中 [参考图片 2]

3.) 在“添加 Jar/Aar 依赖项”对话框中,首先输入 .aar 或 .jar 文件的路径,然后 select 应用依赖项的配置。如果库应该对所有配置可用,select“实现”配置。 [参考图 3]

4.) 点击 OK 然后 Apply > OK.

一切顺利。

使用此代码时出现同样的错误。

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')

编辑:如果 AAR 不包含 android 资源或本机代码,这可能对您有所帮助。

如果您希望此本地资源直接链接到“app”或“sdk”模块 (无编译)

=> 使用罐子.

  • 将 .aar 重命名为 .zip
  • 提取它
  • 使用里面的classes.jar

就是这样。

您可以将 AAR 上传到 Artifactory 并使用它们。

我遇到了同样的问题,从某种意义上说,我想将一个库依赖项封装到一个模块中。然而,这个库依赖有一堆 aar,创建单独的模块每个都是混乱的,甚至在新工作室中找不到那个选项。

为了解决这个问题,我在开始构建过程之前将 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:这也适用于 CI,如果你 运行 清理然后你的下一个任务。

根据我的经验,当 Gradle 插件版本为 4.2.2+ 且 Gradle 版本为 7.1+ 时,如@Luis 的回答 'compileOnly' 有效。

compileOnly files('libs/your_library_name.aar')

Gradle 版本较低时,它不起作用。

如果您想在您的库中捆绑一个本地 .aar 并在另一个项目中使用该库,您可以查看“fat aars” https://github.com/kezong/fat-aar-android

在 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")
    }
}

这样,当您向文件夹添加或删除 dep 时,它们会自动配置

就我而言,我意识到我在错误的位置创建了 libs 文件夹,然后在 main 文件夹中重新创建了文件夹并且 implementation fileTree(include: ['*.aar'], dir: 'libs') 成功了。

我想提一下@StefMa 对这个问题的评论,它非常简单并为我解决了这个问题,但它被埋没在这个线程的许多其他评论中,很容易被遗漏。

此线程上的 'correct' 答案不再有效,因为无法再如该答案中所述在 Android Studio 中导入 AAR。但是,链接到 this GitHub post 的 StefMa 评论中提到的解决方案确实有效,而且效果很好。

长话短说 - 将您的 AAR 放入单独的模块中。

无需费心创建 lib 目录,只需按照以下说明操作即可 -

  1. 在项目的根目录中创建一个新目录。下图显示了其中两个 - spotify-app-remotespotify-auth,但一个就足够了。在其中,放入您的 AAR,并创建一个新的 build.gradle 文件。

  1. build.gradle 文件中,添加以下内容,将 aar 文件名替换为您的 AAR 文件的名称 -
configurations.maybeCreate("default")
artifacts.add("default", file('spotify-app-remote-release-0.7.1.aar'))
  1. 将此添加到您的 settings.gradle 文件中,替换为您创建的目录的名称

include ':spotify-app-remote'

  1. 将您的新模块包含在您希望使用 AAR 的模块中。例如,如果您想在 app 模块中使用它,请打开应用程序的 build.gradle 并添加

api project(':spotify-app-remote')

在你的 dependencies { } 块中,显然再次用你的模块名称替换 spotify-app-remote。

对我来说,这个解决方案有效: 在 build.gradle:app file 这个字符串中加入依赖:

api fileTree(dir: 'libs', include: ['*.aar'])

使 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-groupmy-library-modulemy-library-version 替换为您喜欢的任何值