带有多模块android库的Gradle配置 [英] Gradle configuration with multi-module android library

查看:230
本文介绍了带有多模块android库的Gradle配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有这个可以使用的android库 aar 通常与

  compile'c​​om.companyname.sdk:android-sdk:2.x'

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



在这个重新组织中,我们设法将lib分解成模块。所以人们可以说在V3上我们会有以下工件:

  compile'c​​om.companyname.sdk:core:3.x '
compile'c​​om.companyname.sdk:extra_1:3.x'
compile'c​​om.companyname.sdk:extra_2:3.x'
compile'c​​om.companyname.sdk:extra_ ....

这会在gradle结构中给出以下模块:

  root:
| - test_app(apk只是用于测试,不会在任何地方部署)
| - sdk(aka:core)
| - extra_1
| - extra_2
| - extra_ ... etc


$ b $在 build.gradle 上为每个 extra 模块提供了一个 :sdk'),这样就可以使用 sdk 模块中的所有内容,但实际上并不会自己编译它。



但我想为现有的主机应用程序提供一个简单的迁移路径。意思是,我想在V3上也有下面的结合 core extra_1 的工件(它基本上是当前的东西

  compile'c​​om.companyname.sdk:android-sdk:3.0.0'
code>

这在理论上听起来很棒,但我很难找出一个gradle结构来让我轻松导出所有这些。

我想达到什么

所以我想能够在构建过程中生成以下工件:


  • android-sdk 包括核心 extra_1

  • 核心

  • extra_1

  • ...所有其他额外资讯
  • li>


我试过了什么


  • 添加一个名为 legacy 的额外模块,在没有任何代码的情况下应用 com.android.library 并为其他模块添加 compile project 。它使用两个模块的sourceSets生成一个空的 aar


  • 添加core / legacy buildTypes。从未生成2 aar


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

  • 使用编译项目('extra_1')添加核心/遗留productFlavours 。不会编译,因为sdk和extra_1之间存在循环依赖关系。

  • / p>

    基于Gabrielle的回答,我最终深入挖掘并发现创建一个具有依赖项的额外模块的选项是正确的。它将生成一个空清单和空类的AAR。但重要的部分是它将生成的POM文件,它将包含正确的依赖关系。



    关于该方法的一个警告是针对 maven-publish 插件。通常你需要一个发布对象,其中出版物和一个 pom.withXml 节点。我的如下所示:

      pom.withXml {
    def root = asNode()
    def license = ('''''''')。
    license.appendNode('url','license')。appendNode('license')
    license.appendNode('name','The Apache Software License,Version 2.0' 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)
    }
    }



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



    解决方案存在一些简单的问题,正确的版本号。我看起来像:

      dependencyNode.appendNode('version',$ {rootProject.ext.SDK_VERSION})


    解决方案

    您应该这样做:

      root:
    | - test_app(apk只用于测试,不会在任何地方部署)
    | - core
    | - extra_1
    | - extra_2
    | - extra_ ... etc
    | - android-sdk



    $ core / build.gradle

      apply plugin:'com.android.library'
    // ...

    extra1 / build.gradle

      apply plugin:'com.android。库'
    // ...
    依赖关系{
    编译项目(':core')
    }

    android-sdk / build.gradle

    应用插件:'com.android.library'
    // ...
    依赖关系{
    编译项目(':core')
    c ompile project(':extra')
    }


    Back history

    I have this android library aar that devs can use normally with

    compile 'com.companyname.sdk:android-sdk:2.x'
    

    and now we're doing a re-write of the library from scratch to create V3.

    On this re-organization we managed to break the lib into modules. So one could say that on V3 we would have the following artifacts

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

    and this would give on the gradle structure the following modules:

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

    for each extra module on their build.gradle there's a provided (':sdk') so that can use everything from the sdk module, but do not actually compile it inside themselves.

    but I would like to also provide a easy migration path for existing host apps. Meaning, I would like on V3 to also have the following artifact that combines core and extra_1 (which it's basically what's currently on V2).

    compile 'com.companyname.sdk:android-sdk:3.0.0'
    

    That all sounds great on theory but I'm having a really hard time figuring it out a gradle structure to allow me to easily export all those.

    What I want to achieve

    So I would like to be able to during a build generate the following artifacts:

    • android-sdk that includes both core and extra_1
    • core
    • extra_1
    • ... all other extras

    What have I tried

    • add an extra module named legacy, apply com.android.library without any code and add compile project for both other modules. It generates an empty aar

    • add core/legacy buildTypes with the sourceSets from both modules. Never generated 2 aar

    • add core/legacy productFlavours with sourceSets from both modules. Doesn't compile because it can't find the imports from sdk that are declared into extra_1 (some of which are generated during annotation processor, or lombok)

    • add core/legacy productFlavours with compile project('extra_1'). Doesn't compile because there's a cyclic dependency between sdk and extra_1.

    Answer

    Based on Gabrielle answer I ended up digging more and found that the option to create an extra module with the dependencies is the right one. It will generate an AAR with empty manifest and empty classes. But the important part is the POM file that it will generate that will include the right dependencies.

    A caveat on the approach is on the configuration for the maven-publish plugin. Normally you need a publishing object with publications and a pom.withXml node. mine was like following:

       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)
                    }
                }
    

    The issue with that approach is that dependency.version (at the end) is unspecified, and as such it generates a POM file with <version>unspecified</version>.

    The solution there is simple thou, replace the late with some variable u have on the script with the right version number. Mine looked like:

    dependencyNode.appendNode('version', "${rootProject.ext.SDK_VERSION}")
    

    解决方案

    You should do something like this:

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

    In core/build.gradle:

    apply plugin: 'com.android.library'
    //...
    

    In extra1/build.gradle:

    apply plugin: 'com.android.library'
    //...
    dependencies {
       compile project(':core')
    }
    

    In android-sdk/build.gradle:

    apply plugin: 'com.android.library'
    //...
    dependencies {
       compile project(':core')
       compile project(':extra')
    }
    

    这篇关于带有多模块android库的Gradle配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆