具有捆绑依赖性的库(fat aar)

时间:2015-02-19 11:37:12

标签: android gradle android-library

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

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

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

library是一个Android库,volleyokvolley以及networkstate也是如此。

现在,当我发布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生成一个胖子。

我在本地模块上试过这个

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 ...

3 个答案:

答案 0 :(得分:9)

我有类似的要求,所以在搜索了很多后我最终通过android插件破解了我的方式。我不太了解groovy,但我可以设法制作一个gradle文件,它确实构建了一个app a接受的胖文件。

结果代码可在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存储库嵌入库
  7. 虽然嵌入式库的libs文件夹中的jar文件已解压缩并合并,但只能嵌入android库(aar)而不是jar文件。

    尝试一下,让我知道任何问题。您可以浏览代码并根据需要进行修改。

答案 1 :(得分:6)

我根本不鼓励根据另一个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团队的理由背后不允许将一个安卓库嵌入到另一个(除了#34;它的复杂"),但是根据目前的情况,'更容易将所有Android内容保存在一个模块中。

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

答案 2 :(得分:2)

正式不支持捆绑的aar。以下是来自谷歌技术领导者的answer

我制作了一个侵入Android插件的gradle插件:fat-aar-plugin

它基本上和adwiv的一样。

希望它有所帮助。