我们构建了一个库,并将其分发给客户。我们分发原始的aar文件供他们使用。我们还使用GitHub的原始访问API来提供Maven存储库。
现在为了保持整洁,我们将库划分为几个模块:
include ':library'
include ':geohash'
include ':networkstate'
include ':okvolley'
include ':volley'
library
是Android库,volley
、okvolley
和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:unspecified
和android-sdk:okvolley:unspecified
显示在外部依赖项列表中。
我想用捆绑的本地模块创建我的library
aar。它应该做一个本地清单合并和远震。。。并合并所有模块的依赖关系。应仅显示外部模块。
我确实尝试过引用各个模块的build/output/aar
文件夹中的本地aar文件,但这似乎也不起作用。它似乎仍然通过名称引用本地模块,而不是合并jar的清单。。。
有人做过这样的事吗?在安卓系统之外,这将被称为fatjar,还有一些插件,如musketyr/gradle fatjar插件,可以用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。。。
我只是不鼓励让android库依赖于另一个android库。没有官方支持在输出aar中捆绑android库(请参阅:https://stackoverflow.com/a/20715155/2707179)我认为在可预见的未来不会发生。
因此,目前最简单的方法是将所有与android相关的东西保存在一个模块中,而将其他模块保存为纯java。
绑定普通的java模块非常容易(只需将输出类或输出jar复制到gradle中的android库中),但android模块要困难得多。在某个时候,有一个很好的渐变脚本https://github.com/adwiv/android-fat-aar.不幸的是,它不再被维护,也不适用于最新的android gradle插件。安卓插件中的更改没有很好的文档记录,因此创建(和维护)自己的自定义插件/脚本将非常痛苦。
我真的不理解安卓团队不允许将一个安卓库嵌入另一个库背后的理由(除了"它很复杂"),但在目前的情况下,将所有安卓内容保存在一个模块中要容易得多。
当然,将你的项目模块化是个好主意。我真的试着保留单独的模块,但在某个时候我不得不放弃,所有这些解决方案都不值得。
我也有类似的要求,所以在搜索了很多之后,我最终破解了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文件,因为我不使用它们。以下功能已经存在并且适用于我(尽管我的库并不太复杂)
- 类的合并(因此proguard处理合并类)
- 资产和JNI库的合并
- 合并宣言
- 资源的合并
- 嵌入来自同一项目的库
- 从Maven存储库嵌入库
只有android库(aar)可以嵌入,而不能嵌入jar文件,尽管嵌入库的libs文件夹中的jar文件是解压缩和合并的。
试试看,有什么问题就告诉我。您可以浏览代码并根据需要对其进行修改。
我制作了一个破解安卓插件的gradle插件:fat-aar插件。
它基本上和adwiv的一样。
希望能有所帮助。
现在面临同样的问题,一种选择是在您自己的DevOps包控制器上发布这些Android Java模块,然后从您想要实现它们的模块中指向它们。