buildConfigField 取决于风味 buildType
•浏览 1
buildConfigField depending on flavor + buildType
我正在尝试根据风味 buildType 定义一个 buildConfigVariable。理想情况下,这就是我想要的
productFlavors {
strawberry {
buildConfigField"String","WS_API_KEY", name + variant.buildType.name
}
... more flavors ..
}android.applicationVariants.all { variant ->
println"****************************"
println"variant: ${variant.name}"
println"flavor: ${variant.flavorName}"
println"****************************"
if (variant.buildType.name == 'release') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_release"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_release"'
}
} else if(variant.buildType.name == 'debug') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_debug"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_debug"'
}
}
****************************
variant: strawberryRelease
flavor: strawberry
****************************
org.gradle.api.internal.MissingMethodException:
Could not find method buildConfigField()
for arguments [String, WS_API_KEY,"strawberry_release"]applicationVariants.all { variant ->
variant.buildConfigField"int","VALUE","1"
}applicationVariants.all { variant ->
variant.buildConfigField"String","WS_API_KEY", variant.productFlavors.get(0).name + '_' + variant.buildType.name
}applicationVariants.all { variant ->
variant.mergedFlavor.buildConfigField"String","NAME", '"VALUE"'
}final projectName = project.name
gradle.taskGraph.beforeTask { Task task ->
if (task.path ==~ /:$projectName:generate.*BuildConfig/) {
//extracts flavor and buildType name. See http://stackoverflow.com/a/7594052/218473 for regex
final values = task.name.replace("generate","").replace("BuildConfig","").split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])")
final flavorName = values[0].toLowerCase()
final buildTypeName = values[1].toLowerCase()
com.android.build.gradle.api.ApplicationVariant variant;
android.applicationVariants.all { currentVariant ->
if (currentVariant.getVariantData().getVariantConfiguration().getBuildType().getName() == buildTypeName) {
if (currentVariant.getVariantData().getVariantConfiguration().getFlavorName() == flavorName) {
variant = currentVariant;
}
}
}
if(variant != null) {
com.android.builder.internal.ClassFieldImpl apiKeyField
if (flavorName == 'strawberry') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_debug"')
}
} else if (flavorName == 'chocolate') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_debug"')
}
}
variant.getVariantData().getVariantConfiguration().getFlavorConfigs().get(0).addBuildConfigField(apiKeyField)
}
}
}
name 确实包含"strawberry",但我不知道是否可以访问该变体的 buildType。
放置在 Android 闭包之外,我确实可以访问 BuildType 和变体,但是我不能调用 buildConfigField
productFlavors {
strawberry {
buildConfigField"String","WS_API_KEY", name + variant.buildType.name
}
... more flavors ..
}android.applicationVariants.all { variant ->
println"****************************"
println"variant: ${variant.name}"
println"flavor: ${variant.flavorName}"
println"****************************"
if (variant.buildType.name == 'release') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_release"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_release"'
}
} else if(variant.buildType.name == 'debug') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_debug"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_debug"'
}
}
****************************
variant: strawberryRelease
flavor: strawberry
****************************
org.gradle.api.internal.MissingMethodException:
Could not find method buildConfigField()
for arguments [String, WS_API_KEY,"strawberry_release"]applicationVariants.all { variant ->
variant.buildConfigField"int","VALUE","1"
}applicationVariants.all { variant ->
variant.buildConfigField"String","WS_API_KEY", variant.productFlavors.get(0).name + '_' + variant.buildType.name
}applicationVariants.all { variant ->
variant.mergedFlavor.buildConfigField"String","NAME", '"VALUE"'
}final projectName = project.name
gradle.taskGraph.beforeTask { Task task ->
if (task.path ==~ /:$projectName:generate.*BuildConfig/) {
//extracts flavor and buildType name. See http://stackoverflow.com/a/7594052/218473 for regex
final values = task.name.replace("generate","").replace("BuildConfig","").split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])")
final flavorName = values[0].toLowerCase()
final buildTypeName = values[1].toLowerCase()
com.android.build.gradle.api.ApplicationVariant variant;
android.applicationVariants.all { currentVariant ->
if (currentVariant.getVariantData().getVariantConfiguration().getBuildType().getName() == buildTypeName) {
if (currentVariant.getVariantData().getVariantConfiguration().getFlavorName() == flavorName) {
variant = currentVariant;
}
}
}
if(variant != null) {
com.android.builder.internal.ClassFieldImpl apiKeyField
if (flavorName == 'strawberry') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_debug"')
}
} else if (flavorName == 'chocolate') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_debug"')
}
}
variant.getVariantData().getVariantConfiguration().getFlavorConfigs().get(0).addBuildConfigField(apiKeyField)
}
}
}
我可以轻松创建 Java 工厂并根据一些 BuildConfig 常量返回适当的 API_KEY,但我宁愿保持代码配置不可知。
Edit2:0.14.2 之后的版本将允许这样做:
productFlavors {
strawberry {
buildConfigField"String","WS_API_KEY", name + variant.buildType.name
}
... more flavors ..
}android.applicationVariants.all { variant ->
println"****************************"
println"variant: ${variant.name}"
println"flavor: ${variant.flavorName}"
println"****************************"
if (variant.buildType.name == 'release') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_release"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_release"'
}
} else if(variant.buildType.name == 'debug') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_debug"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_debug"'
}
}
****************************
variant: strawberryRelease
flavor: strawberry
****************************
org.gradle.api.internal.MissingMethodException:
Could not find method buildConfigField()
for arguments [String, WS_API_KEY,"strawberry_release"]applicationVariants.all { variant ->
variant.buildConfigField"int","VALUE","1"
}applicationVariants.all { variant ->
variant.buildConfigField"String","WS_API_KEY", variant.productFlavors.get(0).name + '_' + variant.buildType.name
}applicationVariants.all { variant ->
variant.mergedFlavor.buildConfigField"String","NAME", '"VALUE"'
}final projectName = project.name
gradle.taskGraph.beforeTask { Task task ->
if (task.path ==~ /:$projectName:generate.*BuildConfig/) {
//extracts flavor and buildType name. See http://stackoverflow.com/a/7594052/218473 for regex
final values = task.name.replace("generate","").replace("BuildConfig","").split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])")
final flavorName = values[0].toLowerCase()
final buildTypeName = values[1].toLowerCase()
com.android.build.gradle.api.ApplicationVariant variant;
android.applicationVariants.all { currentVariant ->
if (currentVariant.getVariantData().getVariantConfiguration().getBuildType().getName() == buildTypeName) {
if (currentVariant.getVariantData().getVariantConfiguration().getFlavorName() == flavorName) {
variant = currentVariant;
}
}
}
if(variant != null) {
com.android.builder.internal.ClassFieldImpl apiKeyField
if (flavorName == 'strawberry') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_debug"')
}
} else if (flavorName == 'chocolate') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_debug"')
}
}
variant.getVariantData().getVariantConfiguration().getFlavorConfigs().get(0).addBuildConfigField(apiKeyField)
}
}
}
所以你可以做这样的事情(以匹配原始问题):
productFlavors {
strawberry {
buildConfigField"String","WS_API_KEY", name + variant.buildType.name
}
... more flavors ..
}android.applicationVariants.all { variant ->
println"****************************"
println"variant: ${variant.name}"
println"flavor: ${variant.flavorName}"
println"****************************"
if (variant.buildType.name == 'release') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_release"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_release"'
}
} else if(variant.buildType.name == 'debug') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_debug"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_debug"'
}
}
****************************
variant: strawberryRelease
flavor: strawberry
****************************
org.gradle.api.internal.MissingMethodException:
Could not find method buildConfigField()
for arguments [String, WS_API_KEY,"strawberry_release"]applicationVariants.all { variant ->
variant.buildConfigField"int","VALUE","1"
}applicationVariants.all { variant ->
variant.buildConfigField"String","WS_API_KEY", variant.productFlavors.get(0).name + '_' + variant.buildType.name
}applicationVariants.all { variant ->
variant.mergedFlavor.buildConfigField"String","NAME", '"VALUE"'
}final projectName = project.name
gradle.taskGraph.beforeTask { Task task ->
if (task.path ==~ /:$projectName:generate.*BuildConfig/) {
//extracts flavor and buildType name. See http://stackoverflow.com/a/7594052/218473 for regex
final values = task.name.replace("generate","").replace("BuildConfig","").split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])")
final flavorName = values[0].toLowerCase()
final buildTypeName = values[1].toLowerCase()
com.android.build.gradle.api.ApplicationVariant variant;
android.applicationVariants.all { currentVariant ->
if (currentVariant.getVariantData().getVariantConfiguration().getBuildType().getName() == buildTypeName) {
if (currentVariant.getVariantData().getVariantConfiguration().getFlavorName() == flavorName) {
variant = currentVariant;
}
}
}
if(variant != null) {
com.android.builder.internal.ClassFieldImpl apiKeyField
if (flavorName == 'strawberry') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_debug"')
}
} else if (flavorName == 'chocolate') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_debug"')
}
}
variant.getVariantData().getVariantConfiguration().getFlavorConfigs().get(0).addBuildConfigField(apiKeyField)
}
}
}
编辑:目前不可能。缺少此 API。
错误:https://code.google.com/p/android/issues/detail?id=67416
试试这个:
productFlavors {
strawberry {
buildConfigField"String","WS_API_KEY", name + variant.buildType.name
}
... more flavors ..
}android.applicationVariants.all { variant ->
println"****************************"
println"variant: ${variant.name}"
println"flavor: ${variant.flavorName}"
println"****************************"
if (variant.buildType.name == 'release') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_release"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_release"'
}
} else if(variant.buildType.name == 'debug') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_debug"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_debug"'
}
}
****************************
variant: strawberryRelease
flavor: strawberry
****************************
org.gradle.api.internal.MissingMethodException:
Could not find method buildConfigField()
for arguments [String, WS_API_KEY,"strawberry_release"]applicationVariants.all { variant ->
variant.buildConfigField"int","VALUE","1"
}applicationVariants.all { variant ->
variant.buildConfigField"String","WS_API_KEY", variant.productFlavors.get(0).name + '_' + variant.buildType.name
}applicationVariants.all { variant ->
variant.mergedFlavor.buildConfigField"String","NAME", '"VALUE"'
}final projectName = project.name
gradle.taskGraph.beforeTask { Task task ->
if (task.path ==~ /:$projectName:generate.*BuildConfig/) {
//extracts flavor and buildType name. See http://stackoverflow.com/a/7594052/218473 for regex
final values = task.name.replace("generate","").replace("BuildConfig","").split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])")
final flavorName = values[0].toLowerCase()
final buildTypeName = values[1].toLowerCase()
com.android.build.gradle.api.ApplicationVariant variant;
android.applicationVariants.all { currentVariant ->
if (currentVariant.getVariantData().getVariantConfiguration().getBuildType().getName() == buildTypeName) {
if (currentVariant.getVariantData().getVariantConfiguration().getFlavorName() == flavorName) {
variant = currentVariant;
}
}
}
if(variant != null) {
com.android.builder.internal.ClassFieldImpl apiKeyField
if (flavorName == 'strawberry') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_debug"')
}
} else if (flavorName == 'chocolate') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_debug"')
}
}
variant.getVariantData().getVariantConfiguration().getFlavorConfigs().get(0).addBuildConfigField(apiKeyField)
}
}
}
警告:这可能是一个脆弱的解决方案,使用风险自负。请参阅 https://code.google.com/p/android/issues/detail?id=67416
我就是这样完成了我想要的。您需要在任务执行之前更改值,所以我需要一种方法将我的代码挂在那里。
productFlavors {
strawberry {
buildConfigField"String","WS_API_KEY", name + variant.buildType.name
}
... more flavors ..
}android.applicationVariants.all { variant ->
println"****************************"
println"variant: ${variant.name}"
println"flavor: ${variant.flavorName}"
println"****************************"
if (variant.buildType.name == 'release') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_release"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_release"'
}
} else if(variant.buildType.name == 'debug') {
if (variant.flavorName == 'strawberry') {
buildConfigField"String","WS_API_KEY", '"strawberry_debug"'
} else {
buildConfigField"String","WS_API_KEY", '"chocolate_debug"'
}
}
****************************
variant: strawberryRelease
flavor: strawberry
****************************
org.gradle.api.internal.MissingMethodException:
Could not find method buildConfigField()
for arguments [String, WS_API_KEY,"strawberry_release"]applicationVariants.all { variant ->
variant.buildConfigField"int","VALUE","1"
}applicationVariants.all { variant ->
variant.buildConfigField"String","WS_API_KEY", variant.productFlavors.get(0).name + '_' + variant.buildType.name
}applicationVariants.all { variant ->
variant.mergedFlavor.buildConfigField"String","NAME", '"VALUE"'
}final projectName = project.name
gradle.taskGraph.beforeTask { Task task ->
if (task.path ==~ /:$projectName:generate.*BuildConfig/) {
//extracts flavor and buildType name. See http://stackoverflow.com/a/7594052/218473 for regex
final values = task.name.replace("generate","").replace("BuildConfig","").split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])")
final flavorName = values[0].toLowerCase()
final buildTypeName = values[1].toLowerCase()
com.android.build.gradle.api.ApplicationVariant variant;
android.applicationVariants.all { currentVariant ->
if (currentVariant.getVariantData().getVariantConfiguration().getBuildType().getName() == buildTypeName) {
if (currentVariant.getVariantData().getVariantConfiguration().getFlavorName() == flavorName) {
variant = currentVariant;
}
}
}
if(variant != null) {
com.android.builder.internal.ClassFieldImpl apiKeyField
if (flavorName == 'strawberry') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"strawberry_debug"')
}
} else if (flavorName == 'chocolate') {
if (buildTypeName == 'release') {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_release"')
} else {
apiKeyField = new com.android.builder.internal.ClassFieldImpl("String","WS_API_KEY", '"chocolate_debug"')
}
}
variant.getVariantData().getVariantConfiguration().getFlavorConfigs().get(0).addBuildConfigField(apiKeyField)
}
}
}
要了解其工作原理,请下载 AOSP 源代码并检查 VariantConfiguration.getBuildConfigItems()
使用 Xavier 的答案会引发 MethodMissingError。如果我使用 variant.mergedFlavor.addBuildConfigField() 没有错误,但没有添加变量。