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

vol*_*nde 23 android gradle android-library

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

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

include ':library'
include ':geohash'
include ':networkstate'
include ':okvolley'
include ':volley'
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

正如您所见,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'
}
Run Code Online (Sandbox Code Playgroud)

直接引用aar ...

Adw*_*wiv 8

我有一个类似的要求,所以经过搜索很多我最终通过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'
}
Run Code Online (Sandbox Code Playgroud)

当前代码不会尝试合并AIDL文件,因为我不使用它们.以下功能适用于我(虽然我的库不太复杂)

  1. 合并类(所以proguard适用于组合的clases)
  2. 合并资产和JNI库
  3. 合并清单
  4. 合并资源
  5. 从同一个项目嵌入库
  6. 从Maven存储库嵌入库

虽然嵌入式库的libs文件夹中的jar文件已解压缩并合并,但只能嵌入android库(aar)而不是jar文件.

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


mic*_*brz 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团队的理由背后不允许将一个安卓库嵌入到另一个(除了"它很复杂"),但是根据目前的情况,将所有Android内容保存在一个模块中要容易得多.

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