为特定的flavor和buildType定义buildconfigfield



我有两种口味,比如香草和巧克力。我也有调试和发布构建类型,我需要香草发布有一个字段为真,而其他3个组合应该是假的。

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
    }

我有一个错误,所以我猜调试和释放技巧不起作用。这是可能的吗?

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

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

这是我在Simas回答

中描述的一个没有缺陷的解决方案
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]}""
}

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

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

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

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

defaultConfig {
    buildConfigField BOOLEAN, VARIABLE, TRUE
}
buildTypes {
    debug {
        buildConfigField BOOLEAN, VARIABLE, FALSE
    }
    release {
    }
}
productFlavors {
    VANILLA {
    }
    CHOCOLATE {
        buildConfigField BOOLEAN, VARIABLE, FALSE
    }
}

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

我是这样解决的:

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是否存在于风味中)

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

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]}"
        }

@Simas答案是正确的,但它可能看起来稍微好一点切换情况:

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

我已经用以下方法解决了(.kts)

 applicationVariants.all {
        when {
            flavorName.contains("flavor1", true) && buildType.name.equals("debug", true) -> {
                buildConfigField("String", "BACKEND_URL", ""https://api.dev.flavor1.com"")
            }
            flavorName.contains("flavor1", true) && buildType.name.equals("release", true) -> {
                buildConfigField("String", "BACKEND_URL", ""https://api.prod.flavor1.com"")
            }
            flavorName.contains("flavor2", true) && buildType.name.equals("debug", true) -> {
                buildConfigField("String", "BACKEND_URL", ""https://api.dev.flavor2.com"")
            }
            flavorName.contains("flavor2", true) && buildType.name.equals("release", true) -> {
                buildConfigField("String", "BACKEND_URL", ""https://api.prod.flavor2.com"")
            }
        }
}

当每种风格/构建类型组合的url彼此之间存在重大差异时,可以使用此解决方案。

此外,使用applicationVariants.all{ .. } 而不使用 lambda参数也是很重要的。

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

最新更新