Gradle buildType/productFlavor 使用意外的 buildConfigField

Posted

技术标签:

【中文标题】Gradle buildType/productFlavor 使用意外的 buildConfigField【英文标题】:Gradle buildType/productFlavor using unexpected buildConfigField 【发布时间】:2015-07-25 20:10:39 【问题描述】:

给定以下配置:

productFlavors 
  normal 
    applicationId "com.app"
  

  mock 
    applicationId "com.app.mock"
  


buildTypes 
  debug 
    productFlavors.normal.buildConfigField "boolean", "mockMode", "false"
    productFlavors.mock.buildConfigField "boolean", "mockMode", "true"
  

  release 
    productFlavors.normal.buildConfigField "boolean", "mockMode", "false"
    // Release should never point to mocks. Ever.
    productFlavors.mock.buildConfigField "boolean", "mockMode", "false"
  

我原以为BuildConfig.mockMode = true;,但是,这是生成的构建配置:

public final class BuildConfig 
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "*****";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "mock";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from product flavor: mock
  public static final boolean mockMode = false;

通过一些调查/调试,我意识到如果我在发布 buildType 中更改产品风味的值,它实际上会更新 BuildConfig.mockMode 值,尽管已选择 mockDebug 作为我的构建变体。

我已经有了更好的解决方案来实现我想做的事情,所以我只是在寻找一个答案,以帮助我理解为什么 Gradle 根据配置以这种方式行事,以帮助我更多地了解它在做什么。

【问题讨论】:

【参考方案1】:

您可以将决定 BuildConfig 字段实际值的逻辑提取到它自己的方法中。这样,DSL 配置就只有一条线路。它看起来像这样(未经测试 - 预期语法错误):

buildTypes 
    applicationVariants.all  variant ->
        variant.buildConfigField "boolean", "mockMode", mockMode(variant)
    


def mockMode(variant) 
    //Return true or false depending on variant.buildType and variant.productFlavors 

【讨论】:

这是一个不错的解决方案。如果明确定义了所有构建变体(如问题中所示),您是否知道为什么它似乎正在执行所有构建变体中的逻辑?这对我来说似乎很奇怪,这是预期的行为。【参考方案2】:

使用此配置运行后相当容易理解:

buildTypes 
    debug 
        println("debug!")
    
    release 
        println("release!")
    

您将在构建日志中看到:

Information:Gradle tasks [:app:assembleOneDebug]
debug!
release!
:app:preBuild UP-TO-DATE
...

这意味着您的代码的所有 4 行都已执行,因此唯一有效的行是最后 2 行:

productFlavors.normal.buildConfigField "boolean", "mockMode", "false"
productFlavors.mock.buildConfigField "boolean", "mockMode", "false"

这导致您的BuildConfig 拥有:

public static final boolean mockMode = false;

【讨论】:

感谢您的回答,我认为它正在执行两条路径。你知道为什么两条路径都被执行吗?我认为将它们分开的全部意义在于您可以为不同的版本配置不同的值。

以上是关于Gradle buildType/productFlavor 使用意外的 buildConfigField的主要内容,如果未能解决你的问题,请参考以下文章

GroovyGradle 环境搭建 ( 下载 Gradle 工具 | 查找本地缓存的 Gradle 工具 | 配置 Gradle 环境变量 )

Android Gradle 插件Gradle 构建工具简介 ① ( Gradle 环境配置 | 官网下载 Gradle 软件包 | 在本地用户目录下查找 | 配置 Gradle 环境变量 )

Android Gradle 插件Gradle 依赖管理 ① ( org.gradle.api.Project 配置 | Android Gradle 插件配置与 Gradle 配置关联 ) ★

gradle wrapper, gradle ,gradle plugin 之间的关系

Gradle与Gradle插件

Android Gradle 插件Gradle 自动化构建 ① ( Gradle 构建工具简介 | Gradle 构建工具用途 )