【问题标题】:Define buildconfigfield for an specific flavor AND buildType为特定风味和 buildType 定义 buildconfigfield
【发布时间】:2015-08-02 01:17:03
【问题描述】:

我有 2 种口味,比如说香草和巧克力。我也有 Debug 和 Release 构建类型,我需要 Vanilla Release 的字段为 true,而其他 3 个组合应该为 false。

def BOOLEAN = "boolean"
def VARIABLE = "VARIABLE"
def TRUE = "true"
def FALSE = "false"

    VANILLA {

        debug {

            buildConfigField BOOLEAN, VARIABLE, FALSE

        }

        release {

            buildConfigField BOOLEAN, VARIABLE, TRUE

        }


    }

    CHOCOLATE {
        buildConfigField BOOLEAN, VARIABLE, FALSE
    }

我遇到了一个错误,所以我猜调试和发布技巧不起作用。可以这样做吗?

【问题讨论】:

  • 你为什么要重新定义布尔值,真假...
  • 我更喜欢使用 BOOLEAN、TRUE 和 FALSE 而不是“boolean”、“true”和“false”。但是与问题无关
  • 看到这个答案:stackoverflow.com/a/26579662/10793

标签: android gradle android-gradle-plugin build-tools


【解决方案1】:

循环变体并检查它们的名称:

productFlavors {
    vanilla {}
    chocolate {}
}

applicationVariants.all { variant ->
    println("Iterating variant: " + variant.getName())
    if (variant.getName() == "chocolateDebug") {
        variant.buildConfigField "boolean", "VARIABLE", "true"
    } else {
        variant.buildConfigField "boolean", "VARIABLE", "false"
    }
}

【讨论】:

  • 非常感谢!我仍然要等到明天才能提供赏金
  • 这个解决方案有一个不足 - 您使用字符串来确定构建变体。如果有大量 buildConfigFields,您将有一个样板代码。而且你不应该忘记在重命名 buildType 或 productFlavor 后更正检查
  • 如果这是在库而不是应用程序中,像这样的小改动:libraryVariants.all { variant -> variant.outputs.all { println("Iterating variant: ${variant.name}") } }
  • 升级到 Gradle 插件 4.0 后停止工作。 :(你没有偶然的解决方案吗?
  • @GeorgiyShur 这里也有同样的问题,你找到解决方法了吗?
【解决方案2】:

这是我在Simas answer 下描述的一个没有缺陷的解决方案

buildTypes {
    debug {}
    release {}
}

productFlavors {
    vanilla {
        ext {
            variable = [debug: "vanilla-debug value", release: "vanilla-release value"]
        }
    }
    chocolate {
        ext {
            variable = [debug: "chocolate-debug value", release: "chocolate-release value"]
        }
    }
}

applicationVariants.all { variant ->
    def flavor = variant.productFlavors[0]
    variant.buildConfigField "boolean", "VARIABLE", "\"${flavor.variable[variant.buildType.name]}\""
}

【讨论】:

  • 我通常不写“谢谢”cmets,但这真的很有帮助 - 谢谢!顺便说一句,“ext”在这里是强制性的。
【解决方案3】:

不幸的是,在 Gradle 构建系统中,buildTypesproductFlavors 是两个独立的实体。

据我所知,要完成您想要实现的目标,您需要创建另一种构建风格:

buildTypes {
        debug{}
        release {}
    }

    productFlavors {
        vanillaDebug {
             buildConfigField BOOLEAN, VARIABLE, FALSE
        }
        vanillaRelease {
             buildConfigField BOOLEAN, VARIABLE, TRUE
        }
        chocolate {
             buildConfigField BOOLEAN, VARIABLE, FALSE
        }
    }

【讨论】:

  • 谢谢你的回答,这就是我害怕的。使用这种方法,我将有 6 个不同的构建,对吗? vanillaDebugDebug,vanillaDebugRelease,vanillaReleaseDebug,vanillaReleaseRelease,chocolateDebug,chocolateRelease 对吗?我认为这个解决方案不适合我的需求,但我想这个问题没有好的解决方案
  • 我知道这并不理想,但这是目前正确的做法
  • 这样会产生vanillaDebugDebug、vanillaDebugRelease、vanillaReleaseDebug、vanillaReleaseRelease、chocolateDebug、chocolateRelease 是不对的
【解决方案4】:

对于您的具体情况,您也可以使用 defaultConfig:

defaultConfig {
    buildConfigField BOOLEAN, VARIABLE, TRUE
}

buildTypes {
    debug {
        buildConfigField BOOLEAN, VARIABLE, FALSE
    }
    release {
    }
}

productFlavors {
    VANILLA {
    }
    CHOCOLATE {
        buildConfigField BOOLEAN, VARIABLE, FALSE
    }
}

默认值为 TRUE,但随后您将 FALSE 用于所有 Debug 构建和所有 Chocolate 构建。所以唯一剩下的 TRUE 是 VANILLA-release。

【讨论】:

  • 是的,我确实测试过。是的,它有效。正如我所说,这是针对他的特定情况=香草释放TRUE,另一个FALSE。不可能将此方法用于任何组合。 BuildTypes 和 productFlavors 会覆盖 defaultConfig 值。所以想法是默认设置 TRUE,并覆盖为 FALSE 进行调试(香草调试和巧克力调试)和巧克力(调试巧克力和释放巧克力)。所以除了没有被覆盖的释放香草之外,一切都是假的。
  • 当您只是想为一个buildType 添加buildConfigField 时,这是一个非常好的解决方案。如果不将 buildConfigField 添加到其他 buildTypes,它将无法编译。但是使用defaultConfig 就可以了。
【解决方案5】:

我是这样解决这个问题的:

def GAME_DIMENSION = "game"
def BUILD_DIMENSION = "building"

flavorDimensions GAME_DIMENSION, BUILD_DIMENSION

productFlavors {
    lollipop {
        dimension BUILD_DIMENSION
        minSdkVersion 21
    }

    normal {
        dimension BUILD_DIMENSION
    }

    game_1 {
        dimension GAME_DIMENSION
        ext {
            fields = [
                    [type: 'String', name: 'TESTSTRING', values: [debug: 'debugstring', release: 'releasestring']],
                    [type: 'int', name: 'TESTINT', values: [debug: '1234', release: '31337']]
            ]
        }
    }

    game_2 {
        dimension GAME_DIMENSION
        ext {
            fields = []  // none for game_2
        }
    }
}

applicationVariants.all { variant ->

    // get the GAME dimension flavor
    def game = variant.getProductFlavors()
            .findAll({ flavor -> flavor.dimension == GAME_DIMENSION})
            .get(0)

    println "Adding " + game.ext.fields.size() + " custom buildConfigFields for flavor " + variant.name

    // loop over the fields and make appropriate buildConfigField
    game.ext.fields.each { field ->
        def fldType = field['type']
        def fldName = field['name']
        def fldValues = field['values']

        // get debug/release specific value from values array
        def fldSpecificValue = fldValues[variant.getBuildType().name]

        // add quotes for strings
        if (fldType == 'String') {
            fldSpecificValue = '\"' + fldSpecificValue + '\"'
        }

        println "    => " + fldType + " " + fldName + " = " + fldSpecificValue
        variant.buildConfigField fldType, fldName, fldSpecificValue
    }
}

(我还不能确定ext.fields 是否存在于某个风味中)

【讨论】:

    【解决方案6】:

    您可以尝试多种产品口味:

    productFlavors {
            demo {
                applicationId "com.demo"
                versionCode 1
                versionName '1.0'
                ext {
                    APP_BASE_URL = [debug: "${BASE_URL_DEV}", release: "${BASE_URL_PRODUCTION}"]
                }
            }
            demo1 {
                applicationId "com.demo1"
                versionCode 1
                versionName '1.2'
                ext {
                    APP_BASE_URL = [debug: "${BASE_URL_DEV}", release: "${BASE_URL_PRODUCTION}"]
                }
            }
    
    
        applicationVariants.all { variant ->
                def flavor = variant.productFlavors[0]
                variant.buildConfigField "String", "BASE_URL", "${flavor.ext.APP_BASE_URL[variant.buildType.name]}"
            }
    

    【讨论】:

      【解决方案7】:

      @Simas Aswer 是正确的,但使用 switch case 可能会更好一些:

      android {
      
          defaultConfig {
             ...
          }
      
          buildTypes {
              debug {
                  ...
              }
      
              release {
                  ...
              }
      
          }
      
          flavorDimensions "type"
          productFlavors {
      
              vanilla {
                  dimension "type"
                 ...
              }
      
      
              chocolate {
                  dimension "type"
                  ...
              }
          }
      
          applicationVariants.all { variant ->
              switch (variant.getName()) {
                  case "vanillaDebug":
                      variant.buildConfigField 'String', 'SDK_API_KEY', "\"$vanillaSdkApiKeyDebug\""
                      break
      
                  case "vanillaRelease":
                      variant.buildConfigField 'String', 'SDK_API_KEY', "\"$vanillaSdkApiKeyRelease\""
                      break
      
                  case "chocolateDebug":
                      variant.buildConfigField 'String', 'SDK_API_KEY', "\"$chocolateSdkApiKeyDebug\""
                      break
      
                  case "chocolateRelease":
                      variant.buildConfigField 'String', 'SDK_API_KEY', "\"$chocolateSdkApiKeyRelease\""
                      break
      
                  default:
                      throw new GradleException("The values are unknown for variant: ${variant.getName()}")
                      break
              }
          }
      }
      

      【讨论】:

        【解决方案8】:
        productFlavors {
            vanilla {}
            chocolate {}
        }
        
        buildTypes {
                release {
                    productFlavors.vanilla {
                        //your configuration for vanilla flavor with release buildType
                    }
                }
                debug {
                    productFlavors.chocolate{
                        //your configuration for chocolate flavor with debug buildType
                    }
                }
            }
        

        【讨论】:

        • 当你这样做时,它将采用你最后的定义。所以在这种情况下,它将始终使用 debugCocolate 进行编译。当您更改顺序以便将香草定义在巧克力下方时,它将始终采用该顺序。这很可能不是预期的结果。不过,如果能像这样工作就好了。
        猜你喜欢
        • 2014-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-10
        • 2018-05-08
        • 1970-01-01
        • 1970-01-01
        • 2016-03-05
        相关资源
        最近更新 更多