【问题标题】:library with bundles dependencies (fat aar)具有捆绑包依赖项的库(fat aar)
【发布时间】:2015-02-19 11:37:12
【问题描述】:

我们构建了一个库,然后分发给我们的客户。我们分发原始 aar 文件供他们使用。我们还使用 GitHub 的原始访问 API 来提供一个 Maven 存储库。

现在为了保持整洁,我们将库分成几个模块:

include ':library'
include ':geohash'
include ':networkstate'
include ':okvolley'
include ':volley'

library 是一个 Android 库,volleyokvolleynetworkstate 也是。

现在当我发布 library 时,依赖关系树如下所示:

\--- com.sensorberg.sdk:sensorberg-sdk:0.10.0-SNAPSHOT
 +--- com.squareup.okhttp:okhttp-urlconnection:2.2.0
 |    \--- com.squareup.okhttp:okhttp:2.2.0
 |         \--- com.squareup.okio:okio:1.2.0
 +--- com.google.code.gson:gson:2.3.1 
 +--- android-sdk:okvolley:unspecified
 |    +--- com.squareup.okhttp:okhttp-urlconnection:2.2.0 (*)
 |    +--- com.google.code.gson:gson:2.3.1
 |    +--- android-near-gradle:volley:unspecified
 |    \--- com.squareup.okhttp:okhttp:2.2.0 (*)
 +--- android-sdk:networkstate:unspecified
 +--- com.squareup.okhttp:okhttp:2.2.0 (*)
 +--- android-sdk:volley:unspecified
 \--- com.loopj.android:android-async-http:1.4.5

如您所见,android-sdk:networkstate:unspecifiedandroid-sdk:okvolley:unspecified 出现在外部依赖项列表中。

我想创建我的library aar 并捆绑本地模块。它应该做一个本地清单合并和远 jar ......并合并所有模块的依赖关系。应该只显示外部模块。

我确实尝试从各个模块的 build/output/aar 文件夹中引用本地 aar 文件,但这似乎也不起作用。它似乎仍然通过名称引用本地模块,而不是合并 jar 的清单......

有人做过这样的事吗?在 Android 之外,这将被称为 fatjar,并且有像 musketyr/gradle-fatjar-plugin 这样的插件可以使用 Gradle 生成 fatjar。

我在本地模块上试过这个

if (project.ext.libraryBuild == true) {
    def moduleName = getName()
    File artifactFile = file("/build/outputs/aar/${moduleName}-release.aar")
    if (!artifactFile.exists()) {
        throw new GradleException("Dependency ${moduleName} is not build")
    }
    configurations.create("default")
    artifacts.add("default", artifactFile)
    return;
}


apply plugin: 'com.android.library'

android {
    compileSdkVersion 19
    buildToolsVersion = '21.1.2'
}

直接引用 aar...

【问题讨论】:

  • 创建一个包含所有依赖项的 aar,合并清单、资源、类文件。
  • @mins 不。 aar 是从 gradle 创建的。当然,您可以从 UI 触发相同的过程。我想更改类型或 aar。
  • 也许 zip 包含 aar 和 jars?正如我从今天的谈话中了解到的那样,人们根本不想使用 gradle,或者 gradle 但没有适当的依赖关系?
  • 您找到解决方案了吗?

标签: android gradle android-library


【解决方案1】:

我只是不鼓励根据另一个 android 库制作 android 库。没有官方支持在输出 aar 中捆绑 android 库(请参阅:https://stackoverflow.com/a/20715155/2707179),我认为它不会在可预见的将来出现。

因此,目前最简单的方法是将所有与 android 相关的内容放在一个模块中,而将其他模块保留为纯 java。

捆绑纯 java 模块非常容易(只需将输出类或输出 jar 复制到 gradle 中的 android 库),但 android 模块要困难得多。在某个时候,有一个很好的 gradle 脚本 https://github.com/adwiv/android-fat-aar。不幸的是,它不再维护,并且不适用于最新的 android gradle 插件。而且 android 插件的变化没有很好的记录,所以创建(和维护)你自己的自定义插件/脚本会很痛苦。

我真的不明白 Android 团队不允许将一个 android 库嵌入到另一个库中的理由(除了“它很复杂”),但在目前的情况下,将所有 android 的东西放在一个模块中要容易得多。

当然,模块化您的项目是个好主意。我真的试图保持单独的模块,但在某些时候我不得不放弃,所有这些变通方法都不值得。

【讨论】:

    【解决方案2】:

    我有类似的要求,所以在搜索了很多之后,我最终通过 android 插件破解了我的方式。我不太了解 groovy,但我可以设法编写一个 gradle 文件,该文件确实构建了一个被应用程序接受的胖 aar 文件。

    生成的代码可在github.com/adwiv/android-fat-aar 获得。详细说明在 GitHub 站点上。生成的build.gradle 如下所示:

    apply from: 'fat-aar.gradle'
    
    dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
    
      embedded project(':libraryone')
      embedded project('com.example.internal:lib-three:1.2.3')
    
      compile 'com.android.support:appcompat-v7:22.2.0'
    }
    

    当前代码不会尝试合并 AIDL 文件,因为我不使用它们。以下功能存在并且对我有用(尽管我的库不是太复杂)

    1. 类的合并(所以 proguard 对合并的类起作用)
    2. 资产和 JNI 库的合并
    3. 清单合并
    4. 资源合并
    5. 嵌入来自同一项目的库
    6. 从 Maven 存储库嵌入库

    只能嵌入 android 库 (aar),不能嵌入 jar 文件,尽管嵌入库的 libs 文件夹中的 jar 文件已解压缩并合并。

    尝试一下,如果有任何问题,请告诉我。您可以浏览代码并根据需要对其进行修改。

    【讨论】:

    【解决方案3】:

    官方不支持捆绑的 aar。这是来自谷歌技术领导者的answer

    我制作了一个 gradle 插件,可以侵入 android 插件:fat-aar-plugin

    基本上和adwiv的一样。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 2015-10-04
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      相关资源
      最近更新 更多