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

143
我们最近升级到了Android Gradle插件4.0.0-beta03。在构建库模块时,我们现在看到了以下错误: $ ./gradlew library_module:assemble 执行任务':library_module:bundleDebugAar'失败。 > 不支持直接本地.aar文件依赖项来构建AAR。由于任何本地.aar文件依赖项中的类和Android资源都不会打包在生成的AAR中,因此生成的AAR将无法使用。即使在此情况下,之前的Android Gradle插件版本也会产生损坏的AAR(尽管没有抛出此错误)。以下是:library_module项目的直接本地.aar文件依赖项,导致了这个错误:______.aar。
我可以看到这是几个月前添加到AGP的。但他们没有提供更多关于此问题的信息。
所以:
1.这是什么问题?有更多信息吗?我找不到任何错误报告。
2.我该如何解决这个问题?这是否意味着我不能构建一个依赖于其他本地.aar文件的.aar文件?如果这个本地aar文件改为托管在Maven Central或另一个远程repo上,会有什么区别?为什么会有区别?

@spollom@google.com,对此有什么评论吗? - David
整个问题在于这将导致一种类似于fat AAR的东西。 这并不是一个简单的任务,但Google肯定可以做到(因为他们已经拥有所有必要的工具——他们能够将任意数量的AAR合并到APK中),所以他们可能只是不想这样做(因为传递依赖关系在大多数情况下更加合适)。 对于此问题,已经有一个现有的社区解决方案-请参见https://github.com/kezong/fat-aar-android-但请注意,它不够成熟(例如不支持多品味版本构建,或对新的AGP版本的支持来得太晚...)。 - Jiří Křivánek
22个回答

145

最近我也遇到了同样的问题,解决方法是将库从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 的库中:
implementation project(":pathToTheCreatedDirectory", configuration = "default")

9
有了这个解决方案,我们突然需要几个额外的模块。很遗憾关于这个新警告没有更多的信息,对我来说并不是很合理,我们的项目已经按照现有方式运作。 - David
9
提醒一下 - 我正在寻找一个解决方案,使得一个 AAR 文件可以包含另一个 AAR 文件。但是这个答案并没有做到这一点。第二个 AAR 文件已经成功创建了,但它没有与第一个文件捆绑在一起。 - Viktor Brešan
31
在Android Studio 4中,导入.JAR/.AAR包的选项不可用。 - Sabrina
19
当我执行此操作时,出现了“无法为类型为org.gradle.initialization.DefaultSettings的android设置中未知属性'configuration'”,有其他人也遇到这个问题吗?Gradle插件版本为4.2.2。 - Max
9
implementation project(":pathToTheCreatedDirectory", configuration = "default") 引起错误 Could not set unknown property 'configuration'...。____________________ implementation project(":pathToTheCreatedDirectory") 可行。 - Eugene Babich
显示剩余17条评论

115

我想在这个问题上呼吁一下@StefMa的评论,它非常简单,为我解决了这个问题,但是它淹没在许多其他评论中,很容易被忽视。

这个主题上的“正确”答案不再适用,因为在那个答案中提到的在Android Studio中导入AARs已经不可能了。但是,StefMa的评论中提到的链接到这个GitHub帖子的解决方案可以,并且它完美地工作。

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

不需要费力地创建lib目录,只需按照以下说明操作:

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

    Folder structure

  2. 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'
    
  3. 将你的新模块包含在你想要使用AAR的模块中。例如,如果你想在app模块中使用它,在app的build.gradle中打开并添加:

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

    在您的dependencies { }块中,显然需要将spotify-app-remote替换为您的模块的名称。


4
工作完美。谢谢! - Vamsi
12
这应该成为2021年及以后的被接受的答案。手动完成这项任务真的很愚蠢。因此,我相信Android Studio的开发人员并不会如此愚蠢,他们很可能在下一个版本的Android Studio中解决这个问题,那时我们可能需要再次尝试找到另一种方法来完成这个任务。 - deltamind106
3
是否可以通过添加多个artifacts.add子句将多个AAR添加到单个library module中? - Tash Pemhiwa
3
能否创建一个带有这个的示例存储库?我遇到了一个问题,Gradle报告说找不到“Spotify”项目(我在我的代码中使用了自己的名称)。 - Dusan Plavak
2
@ThomasPapapaschos 我在上面发表不满后变聪明了:AAR文件不是用来嵌入的,而是用来作为外部引用库的(类似于NPM)。我最终做的是将我所需的(闭源)AAR文件放在“GitHub Packages”上,作为一个Maven仓库。然后我的应用程序从那里引用AAR文件,并且运行良好。不过,设置起来有点麻烦,需要阅读很多文档,包括Maven文档。祝你好运,这就是我能说的。 - DarkNeuron
显示剩余7条评论

60
在构建依赖其他Android库(即aar文件)的Android库时,如果将aar文件作为项目的依赖项包含进去,您将会收到以下错误消息:

在构建AAR时,不支持直接本地.aar文件依赖项。由于任何本地.aar文件依赖项的类和Android资源都不会打包在生成的AAR中,因此生成的AAR将无法正常工作。即使是之前版本的Android Gradle插件也会在这种情况下生成错误的AAR(尽管没有抛出此错误)。

如上所述,当您构建一个Android库项目时,它所依赖的任何aar都不会被打包。如果您在AGP(Android Gradle Plugin)4之前以这种方式构建,则可能会注意到您必须将aar依赖项包含在使用您的库的项目中。
您可以通过指定aar依赖项为compileOnly来编译您的Android库项目。有关何时使用compileOnly的更多信息,请参见this
因此,只需将以下内容添加到您的appbuild.gradle文件中:
compileOnly files('libs/some-library.aar')

请注意,如果这样做,您将不得不在使用您的库的应用程序项目中包含aar依赖项。
或者,您可以创建一个模块,像上面@Sandi所提到的那样导入您的aar依赖项。
另一种方法是将您的aar依赖项发布到maven存储库,然后像这样将它们添加到您的库项目中:
implementation 'mylibrarygroup:mylibraryartifact:version-x.y.z@aar'

7
不确定这个答案如何帮助任何人。谷歌在文档中说:“您无法将compileOnly配置与AAR依赖项一起使用。”,详情请参见:https://developer.android.com/studio/build/dependencies。 - DarkNeuron
1
@DarkNeuron 这是因为 OP 的用例不同:你有一个库项目,它编译成一个 aar,也依赖于其他 aar。所以对于这种情况,compileOnly 可以使用,但需要注意我的答案中提到的警告(即,在使用该库的项目中必须包含 compile only 的 aar 依赖项)。 - Luis
1
什么?不不,我的用例完全相同:正在构建一个使用AAR的库。我发布了上面的内容,因为它没有起作用。一切都编译了,但是库在最终捆绑包中丢失了。这让我感到困惑,直到我看到了Google的那个注释。无论如何,我通过提取其中包含的JAR文件解决了我的aar问题。这可能并不适用于每个人。 - DarkNeuron
2
@Żabojad,那你没有理解上面的答案。你必须包含依赖项。 - Luis
1
如何在使用您的库的应用程序项目中包含aar依赖项?如何将您的aar依赖项发布到Maven存储库? @Luis - Ahmed Eid
显示剩余4条评论

14

根据我的经验,在Gradle插件版本为4.2.2+且Gradle版本为7.1+时,如@Luis的答案中所示,'compileOnly'可以正常工作。

compileOnly files('libs/your_library_name.aar')

当Gradle版本较低时,它无法正常工作。


15
这样编译后,当我尝试调用该库时,应用程序会崩溃。 - murt
@murt 你有崩溃日志吗? - Vishudh Sasidharan
1
确实编译通过了,但是在运行时aar没有被加载,导致应用程序崩溃。 - Żabojad
2
是的,这只是答案的一半。@Luis的答案添加了重要的补充:“请注意,如果您这样做,您将不得不在使用您的库的应用程序项目中包含aar依赖项。”请参阅Simon的答案以了解如何执行此操作。 - BenClark

9

我也有同样的问题,即想将一个库依赖项封装到一个模块中。然而,这个库依赖项有一堆aars,为每个aars创建单独的模块只会让事情更加混乱,在新版studio中甚至找不到这个选项。

为了解决这个问题,我将aars发布到了本地仓库,然后再开始构建过程。

因此,我的封装模块的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。


2
这才是正确的答案!相比不受支持的AAR依赖项,Maven更受推荐。我一直在寻找一种方法来使用我的本地AARs/artifacts从mavenLocal中获取。感谢@Gergely Hegedus的出色贡献! - Jeff
这个解决方案非常完美,如果你计划发布库,它涵盖了封装。你救了我的一周!! - Son Tieu
@SonTieu,你是否已经将你的库与本地AAR依赖项一起发布到mavenCentral了?这个解决方案适用于mavenCentral还是只适用于mavenLocal? - Kuvonchbek Yakubov
@KuvonchbekYakubov 我尝试使用自己的aar文件,所以这个解决方案在我使用mavenLocal时有效。不过我还没有尝试发布到mavenCentral。 - Son Tieu
如果我的aar有依赖关系,你会如何声明它?我想要像指定我的aar的pom文件一样,同时指定我的aar构件。 - Son Tieu
@SonTieu 理想情况下,您使用的aar应该有一个pom文件,您可以将其附加到maven发布中。如果没有,您需要自己创建该pom文件。gradle链接:https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPom.html#org.gradle.api.publish.maven.MavenPom:withXml(org.gradle.api.Action) - Gergely Hegedus

9

当使用这段代码时,会出现相同的错误。

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

6
现在有一些变化,您需要将您的AARJAR作为依赖项添加。
1.) 首先,导航到文件 > 项目结构 [参考图片1]1 2.) 然后转到依赖项 > 已声明的依赖项选项卡,单击并选择下拉菜单中的JAR/AAR依赖项 [参考图片2]2 3.) 在添加Jar/Aar依赖项对话框中,首先输入您的.aar或.jar文件的路径,然后选择要应用该依赖项的配置。如果库应该对所有配置都可用,请选择“implementation”配置。 [参考图片3]3 4.) 单击确定,然后单击应用 > 确定
您现在可以开始使用它了。

它可以工作!但是文件结构与Sandi的答案不同。 - BobTheCat
2
我尝试过将这个用于库模块但无法正常运行。这就是OP的内容。我非常确定这种方法对于应用程序模块是完美的。 - Hong
我之前做了这个,一切正常直到我重命名了项目目录。尝试重新做,但是现在却无法工作了。 - John T

5

我遇到了类似的问题:

任务:在另一个SDK中添加.aar SDK

解决方案:

  1. We have to create new Android Library Module inside our library (right click on our library name -> module -> Android library )

  2. Delete all files inside it

  3. Insert our .arr inside this module

  4. Create build.gradle file inside module and put there:

    configurations.maybeCreate("default")
    artifacts.add("default", file('your_arr_name.aar'))
    
  5. Add to your library build.gradle inside dependencies block next:

    implementation project(':your_library:your_arr_module')
    
  6. Now rebuild project and everything should work fine


这是我唯一奏效的答案。此外,我不得不手动将创建的模块文件夹移动到我的库文件夹中。我还注意到根级别的 settings.gradle 被附加了 include ':your_library:your_arr_module',如果您要链接React Native库,则包含它非常重要。[我在react-native-spotify-remote库上遇到了问题,在发布Gradle构建时失败,所以我不得不对其进行分支,并应用此修复] - Daniel
我按照这个步骤解决了我的问题,但是遇到了一个新问题:我无法在我的Java代码中获取样式、字符串、绘图和其他资源,例如R.style.xxx, R.string.xxx。 - David

4
在有问题的第三方依赖的build.gradle文件中进行修补。在他们的dependencies { }部分下,他们有一行像这样的代码:
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar']) //Load all aars and jars from libs folder

我的补丁将该行更改为:

implementation(name: 'the-name-of-the-aar', ext: 'aar')

在我的项目的build.gradle文件中,在allprojects { repositories { }下添加了以下内容:
flatDir { dirs "$rootDir/../node_modules/the-third-party-dependency/android/src/main/libs" } 

AAR文件存放位置

已测试通过reactnative >= 0.69.x


1
真的救了我的命。 - mehrab cz
我收到一个警告,建议避免使用flatDir。 - undefined

4

对于那些想要将其作为常规依赖项(或Gradle版本目录中的一项)使用的人:

  1. 创建一个名为spotifyAppRemote的文件夹,与app文件夹在同一级别下
  2. spotifyAppRemote文件夹的根目录中添加所需的.aar文件
  3. spotifyAppRemote文件夹的根目录中创建一个名为settings.gradle.kts的文件。此文件将为空,只需存在于复合构建中。参见:文档
  4. spotifyAppRemote文件夹的根目录中创建一个名为build.gradle.kts的文件:
plugins {
    base //allows IDE clean to trigger clean on this module too
}

configurations.maybeCreate("default")
artifacts.add("default", file("spotify-app-remote-release-0.7.2.aar"))

//Change group to whatever you want. Here I'm using the package from the aar that I'm importing from
group = "com.spotify.android"
version = "0.7.2"
  1. 接下来,将Gradle文件添加到此文件夹中,以允许该模块自行构建。您可以手动完成此操作,也可以将以下代码段添加到settings.gradle.kts的根目录下(!!即项目根目录,而不是上面创建的空文件夹)。
/* Optional - automatically sync gradle files for included build */
rootDir.run {
    listOf(
        "gradle.properties",
        "gradlew.bat",
        "gradlew",
        "gradle/wrapper/gradle-wrapper.jar",
        "gradle/wrapper/gradle-wrapper.properties"
    ).map { path ->
        resolve(path)
            .copyTo(
                target = rootDir.resolve("spotifyAppRemote").resolve(path),
                overwrite = true
            )
    }
}

现在你可以继续将这个文件夹添加为模块到项目根目录下的settings.gradle.kts文件中。与上面添加片段的地方相同:
rootProject.name = "Your project name"
include(":app")
includeBuild("spotifyAppRemote")
  1. 同步并构建你的项目。
  2. 现在你包含的构建将作为一个常规依赖项与定义的组和版本一起提供。要使用这个依赖项:
dependencies {
    // group:moduleName:version
    implementation("com.spotify.android:spotifyAppRemote:0.7.2")
} 

感谢其他成员提供的解决方案。
Github上的源代码: https://github.com/rsicarelli/SpotifySdkCompositeBuild

请提供 Groovy(settings.gradle)的解决方案。 - Palak
2
这个解决方案可以正常工作(库已经构建完成,并且模块类可用),但是如果我将该库导出为 .aar 文件到另一个 Android 项目中,模块代码会丢失。检查库的 .aar 文件后发现,它没有嵌入依赖模块。 - Akamaccio
@matmacci 你能解决它吗?我也有同样的问题。 - Lukáš Šálek
1
@Lukᚊálek 我已经发布了一个新问题,但是还没有人回答。令人难以置信的是,Google没有提供任何关于这个问题的明确信息。 - Akamaccio
我已经将一个库发布到了Maven,这个解决方案可用于解决编译错误。但是,.aar库不会被包含在发布的库中。 - Kuvonchbek Yakubov
1
你真的救了我的一天!你在Github页面上提供了非常准确、详细的解释。谢谢! - Mert Kılıç

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接