Android 为特定样式和buildType定义buildconfigfield

Android 为特定样式和buildType定义buildconfigfield,android,gradle,android-gradle-plugin,build-tools,Android,Gradle,Android Gradle Plugin,Build Tools,我有两种口味,香草和巧克力。我也有Debug和Release构建类型,我需要Vanilla Release将字段设置为true,而其他3个组合应该为false def BOOLEAN = "boolean" def VARIABLE = "VARIABLE" def TRUE = "true" def FALSE = "false" VANILLA { debug { buildConfigField BOOLEAN, VARIABLE, F

我有两种口味,香草和巧克力。我也有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
    }

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

在Gradle构建系统中,
构建类型
产品风格
不幸是两个独立的实体

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

buildTypes {
        debug{}
        release {}
    }

    productFlavors {
        vanillaDebug {
             buildConfigField BOOLEAN, VARIABLE, FALSE
        }
        vanillaRelease {
             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"
    }
}

我是这样解决的:

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

下面是一个解决方案,我已经在下面介绍过了


对于您的特定情况,您也可以使用defaultConfig:

defaultConfig {
    buildConfigField BOOLEAN, VARIABLE, TRUE
}

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

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

默认值为TRUE,但随后将所有调试版本和所有巧克力版本设置为FALSE。因此,唯一剩下的是香草版本。

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

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 Aswer是正确的,但使用开关箱可能会更好一些:

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

为什么你要重新定义布尔、真和假……我更喜欢使用布尔、真和假,而不是“布尔”、“真”和“假”。然而,这与问题无关。看这个答案:谢谢你的回答,这就是我害怕的。使用这种方法,我将有6个不同的构建,对吗?vanillaDebugDebug,vanillaDebugRelease,Vanillarelease,Vanillarelease,chocolateDebug,chocolateRelease,对吗?我认为这个解决方案不适合我的需要,但我想这个问题没有好的解决方案。我知道这并不理想,但目前这是正确的解决方法。这将产生vanillaDebugDebug,vanillaDebugRelease,VanillaleLeaseDebug,VanillaleLeaseRelease,chocolateDebug,chocolateRelease,这是不对的。谢谢!我仍然要等到明天才能给你奖金。这个解决方案有一个缺点——你用字符串来确定构建变量。如果有大量buildConfigFields,您将有一个样板代码。另外,在重命名buildType或ProductFlavor后,如果这是在库中而不是在应用程序中进行的,则不应忘记更正检查,例如:
libraryVariants.all{variant->variant.outputs.all{println(“迭代变量:${variant.name}”)}
升级到Gradle插件4.0后,它停止工作:(你不是碰巧有了一个解决方案吗?@GeorgiyShur这里也有同样的问题,你找到解决方案了吗?当你这么做的时候,它会使用你最后一个定义。所以在这种情况下,它总是用debugCocolate编译。当你改变顺序,使香草在巧克力下面定义时,它总是会这样。这很可能不是你想要的结果。虽然,如果它能像这样工作会很好。我通常不会写“谢谢”的评论,但这真的很有帮助-谢谢!顺便说一句,“ext”这里是强制性的。是的,我测试过。是的,它有效。正如我说的,这是针对他的特定案例=vanillia release TRUE,另一个为FALSE。不可能将此方法用于任何组合。BuildTypes和productFlavors覆盖defaultConfig值。因此,我们的想法是默认设置为TRUE,并覆盖为FALSE进行调试(香草调试和巧克力调试)和巧克力(调试巧克力和释放巧克力)。因此,除了释放未被覆盖的vanillia之外,一切都是错误的。当您尝试为一个
buildType
添加
buildConfigField
时,这是一个非常好的解决方案。如果不将该
buildConfigField
添加到另一个
buildType
中,它将无法编译。但使用
defaultConfig
可以实现这一点。
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]}"
        }
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
        }
    }
}