关于 android:buildConfigField 取决于风味 buildType | 珊瑚贝

buildConfigField depending on flavor + buildType


我正在尝试根据风味 buildType 定义一个 buildConfigVariable。理想情况下,这就是我想要的

1
2
3
4
5
6
productFlavors {
    strawberry {
        buildConfigField”String”,”WS_API_KEY”, name + variant.buildType.name
    }
    … more flavors ..
}

name 确实包含”strawberry”,但我不知道是否可以访问该变体的 buildType。

放置在 Android 闭包之外,我确实可以访问 BuildType 和变体,但是我不能调用 buildConfigField

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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”]

我可以轻松创建 Java 工厂并根据一些 BuildConfig 常量返回适当的 API_KEY,但我宁愿保持代码配置不可知。

  • 另外:如何将 buildConfigField 添加到单个 productFlavors?
  • 这可能会有所帮助。 stackoverflow.com/a/50983681/3333878


Edit2:0.14.2 之后的版本将允许这样做:

1
2
3
applicationVariants.all { variant ->
    variant.buildConfigField”int”,”VALUE”,”1″
}

所以你可以做这样的事情(以匹配原始问题):

1
2
3
applicationVariants.all { variant ->
    variant.buildConfigField”String”,”WS_API_KEY”, variant.productFlavors.get(0).name + ‘_’ + variant.buildType.name
}

编辑:目前不可能。缺少此 API。
错误:https://code.google.com/p/android/issues/detail?id=67416


试试这个:

1
2
3
applicationVariants.all { variant ->
    variant.mergedFlavor.buildConfigField”String”,”NAME”, ‘”VALUE”‘
}

  • 这会引发错误 MissingMethodException: No signature of method: com.android.builder.DefaultProductFlavor.buildConfigField() 适用于参数类型:(java.lang.String, java.lang.String, java.lang.String) 值:[ String, NAME,”VALUE”] 可能的解决方案:getBuildConfigFields()
  • 我有自己的解决方案,但它可能很脆弱,所以我很高兴看到更好的解决方案。我会在 5 分钟内发布它。
  • 哦,是的,mergedFlavor 不适合这个类型。让我看看。
  • 嗨 Xavier,我已经用工作版本更新了我的答案,但我很好奇是否有更好的方法(我想肯定有)。感谢您的工作!
  • 好吧,这看起来很丑陋,但我想现在没有更好的方法。我们必须改进这一点。 code.google.com/p/android/issues/detail?id=67416
  • 谢谢,我会留意那个错误的。
  • @XavierDucrohet 这里有消息吗?


警告:这可能是一个脆弱的解决方案,使用风险自负。请参阅 https://code.google.com/p/android/issues/detail?id=67416

我就是这样完成了我想要的。您需要在任务执行之前更改值,所以我需要一种方法将我的代码挂在那里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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() 没有错误,但没有添加变量。

  • 您可以使用公共 API,不需要 ClassFieldImpl:com.android.builder.model.ClassField apiKeyField 然后声明 def createClassField = com.android.builder.core.AndroidBuilder.&createClassField,然后您可以调用 createClassField(…) 而不是调用 new ClassFieldImpl(…)。


来源:https://www.codenong.com/22506290/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_9796.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?