使用多模块android库进行Gradle配置

Bud*_*ius 6 android gradle android-library android-gradle-plugin aar

回到历史

我有这个aar开发人员可以正常使用的android库

compile 'com.companyname.sdk:android-sdk:2.x'
Run Code Online (Sandbox Code Playgroud)

现在我们正在从头开始重新编写库来创建V3.

在这次重新组织中,我们设法将lib分解为模块.所以可以说在V3上我们会有以下工件

compile 'com.companyname.sdk:core:3.x'
compile 'com.companyname.sdk:extra_1:3.x'
compile 'com.companyname.sdk:extra_2:3.x'
compile 'com.companyname.sdk:extra_ ....
Run Code Online (Sandbox Code Playgroud)

这将在gradle结构上给出以下模块:

root:
  |- test_app (apk just for testing, not deployed anywhere)
  |- sdk (aka: core)
  |- extra_1
  |- extra_2
  |- extra_ ... etc
Run Code Online (Sandbox Code Playgroud)

每个extra在他们的模块build.gradle有一个provided (':sdk'),这样可以使用一切从sdk模块,但不实际编译它自己内部.

但我还想为现有的主机应用程序提供一个简单的迁移路径.意思是,我想在V3上也有以下的神器组合coreextra_1(它基本上是V2上的当前内容).

compile 'com.companyname.sdk:android-sdk:3.0.0'
Run Code Online (Sandbox Code Playgroud)

这一切听起来都很理论,但是我很难把它想象成一个gradle结构,让我轻松导出所有这些.

我想要实现的目标

所以我希望能够在构建期间生成以下工件:

  • android-sdk包括coreextra_1
  • core
  • extra_1
  • ......所有其他额外的东西

我试过了什么

  • 添加一个名为的额外模块legacy,com.android.library无需任何代码即可应用,并compile project为其他模块添加.它会生成一个空的aar

  • 使用两个模块中的sourceSets添加核心/旧版buildTypes.从未生成2aar

  • 使用来自两个模块的sourceSets添加核心/遗留productFlavours.不编译,因为它无法找到sdk声明的导入extra_1(其中一些是在注释处理器或lombok期间生成的)

  • 添加core/legacy productFlavours compile project('extra_1').不编译,因为sdk和extra_1之间存在循环依赖关系.

回答

根据Gabrielle的回答,我最终挖掘了更多,并发现创建带有依赖项的额外模块的选项是正确的.它将生成一个空清单和空类的AAR.但重要的是它将生成的POM文件将包含正确的依赖项.

关于该方法的一个警告是关于maven-publish插件的配置.通常情况下,你需要一个publishing带有对象publications和一个pom.withXml节点.我的如下:

   pom.withXml {
                def root = asNode()
                def license = root.appendNode('licenses').appendNode('license')
                license.appendNode('name', 'The Apache Software License, Version 2.0')
                license.appendNode('url', 'http://www.apache.org/licenses/LICENSE-2.0.txt')
                license.appendNode('distribution', 'repo')
                def dependenciesNode = asNode().appendNode('dependencies')
                configurations.compile.allDependencies.each { dependency ->
                    def dependencyNode = dependenciesNode.appendNode('dependency')
                    dependencyNode.appendNode('groupId', dependency.group)
                    dependencyNode.appendNode('artifactId', dependency.name)
                    dependencyNode.appendNode('version', dependency.version)
                }
            }
Run Code Online (Sandbox Code Playgroud)

这种方法的问题是dependency.version(最后)未指定,因此它生成一个POM文件<version>unspecified</version>.

解决方案有简单的你,用脚本上的一些变量代替正确的版本号.我看起来像:

dependencyNode.appendNode('version', "${rootProject.ext.SDK_VERSION}")
Run Code Online (Sandbox Code Playgroud)

Gab*_*tti 2

你应该做这样的事情:

root:
  |- test_app (apk just for testing, not deployed anywhere)
  |- core 
  |- extra_1
  |- extra_2
  |- extra_ ... etc
  |- android-sdk
Run Code Online (Sandbox Code Playgroud)

core/build.gradle

apply plugin: 'com.android.library'
//...
Run Code Online (Sandbox Code Playgroud)

extra1/build.gradle

apply plugin: 'com.android.library'
//...
dependencies {
   compile project(':core')
}
Run Code Online (Sandbox Code Playgroud)

android-sdk/build.gradle

apply plugin: 'com.android.library'
//...
dependencies {
   compile project(':core')
   compile project(':extra')
}
Run Code Online (Sandbox Code Playgroud)