【问题标题】:Gradle buildType/productFlavor using unexpected buildConfigFieldGradle buildType/productFlavor 使用意外的 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 根据配置以这种方式行事,以帮助我更多地了解它在做什么。

【问题讨论】:

    标签: android groovy 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;
    

    【讨论】:

    • 感谢您的回答,我认为它正在执行两条路径。你知道为什么两条路径都被执行吗?我认为将它们分开的全部意义在于您可以为不同的版本配置不同的值。
    猜你喜欢
    • 2017-05-26
    • 2013-11-04
    • 2014-04-25
    • 2015-08-02
    • 1970-01-01
    • 2014-05-09
    • 2018-08-14
    • 1970-01-01
    • 2016-11-18
    相关资源
    最近更新 更多