【问题标题】:How to emulate Android's productFlavors in a pure java gradle module?如何在纯 java gradle 模块中模拟 Android 的 productFlavors?
【发布时间】:2016-05-17 14:41:28
【问题描述】:

我需要三种口味:

  • fake
  • staging
  • prod

fake 将提供像 FakeUserFakeUserDb 这样的类 - 这些类编译成 prod 风格非常重要。

prodstaging 完全相同,只是我需要将不同的String url 编译成prod vs staging

所以,我需要创建一个prodstaging 都继承的“抽象”real 风格。

这可以通过android gradle 插件轻松完成,但是如何在纯java gradle 模块中完成呢?

【问题讨论】:

  • 您确定这些不能是构建类型吗? AFAIK,构建类型是 Gradle 的东西,Android Plugin for Gradle 碰巧利用了。
  • 哦,它们绝对可以是 buildTypes。在 android 插件术语中,我只需要 stagingDebug、prodRelease 和 fakeDebug
  • @CommonsWare 所以buildType 是一个gradle 概念——不仅仅是一个android 插件概念?有没有纯java的文档?每次谷歌搜索似乎都将我引向了 android 插件
  • 人力资源部。我可以发誓 debugrelease 来自 Gradle。我现在也找不到这方面的信息。我很抱歉。
  • @CommonsWare 似乎有 gradle 在 android 插件之外支持这些东西的耳语,但没有关于它的真正文档。

标签: java android gradle android-gradle-plugin


【解决方案1】:

对于您想要的每种口味

  1. 创建一个SourceSet 以便编译
  2. 使 ${flavour}Compile Configuration 扩展主要的 compile 配置(有关 java 插件创建的每个 SourceSet 的配置,请参见表 45.6 here
  3. 创建JarTask(使用风味作为分类器)
  4. Publish the jar artifact 所以可以通过classifier 引用风味

类似:

def flavours = ['fake', 'staging', 'prod']
flavours.each { String flavour ->
    SourceSet sourceSet = sourceSets.create(flavour)
    sourceSet.java {
       srcDirs 'src/main/java', "src/$flavour/java"
    }
    sourceSet.resources {
       srcDirs 'src/main/resources', "src/$flavour/resources"
    }
    Task jarTask = tasks.create(name: "${flavour}Jar", type: Jar) {
       from sourceSet.output
       classifier flavour
    }
    configurations.getByName("${flavour}Compile").extendsFrom configurations.compile
    configurations.getByName("${flavour}CompileOnly").extendsFrom configurations.compileOnly
    configurations.getByName("${flavour}CompileClasspath").extendsFrom configurations.compileClasspath
    configurations.getByName("${flavour}Runtime").extendsFrom configurations.runtime

    artifacts {
       archives jarTask
    }
    assemble.dependsOn jarTask
}

然后,要在另一个项目中引用其中一种风格,您可以执行以下操作之一:

dependencies {
   compile project(path: ':someProject', configuration: 'fakeCompile')
   compile project(path: ':someProject', configuration: 'fakeRuntime')
   compile 'someGroup:someProject:1.0:fake'
   compile group: 'someGroup', name: 'someProject', version: '1.0', classifier: 'fake'
}

【讨论】:

  • 虽然这很有帮助,但这只是 sourceSets。它不会进入配置,并使某些 gradle 模块依赖于另一个模块的配置
  • 更新了第二个解决方案,为每种风格包含一个工件(具有唯一的分类器)并将其连接到 DAG。然后可以将这些工件包含在下游项目中(通过指定分类器)
  • 太好了,谢谢!使用这些 jar 工件是如何工作的?假设您是从同级 gradle 模块中使用该 jar 吗?
  • 稍微调整以创建每个风味的配置并添加示例参考
  • 谢谢!这很好用,除了我的fake/prod/staging 配置无权访问我在依赖项块中声明的任何第三方库。意思是main 可以访问dependencies { compile "io.reactivex:rxjava:$rxJavaVersion" },但fakestagingprod 没有将rxjava 编译到其类路径中。你如何解决这个问题?
【解决方案2】:

我为此编写了一个 gradle-java-flavors 插件:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多