在build.gradle中定义清单占位符

4

我在AndroidManifest.xml文件中有几个清单占位符。

build.gradle中,我想根据我的风格和构建类型动态填充这些值。

我该怎么做?

我编写了一个执行以下操作的函数

def getKey() {
    def KeyToReturn = ""
    android.applicationVariants.all { variant ->
        printout("getKey: ${variant.name}")
        def flavor = "default";
        if (variant.productFlavors.size() > 0)
            flavor = variant.productFlavors.get(0);


        def buildType = variant.buildType.name

        if (buildType == "debug" || buildType == "staging") {
            if (flavor.name == "one") {
                KeyToReturn = test_key_1
            }
            if (flavor.name == "two") {
                KeyToReturn = test_key_2
            }

        }
        if (buildType == "release") {
            if (flavor.name == "one") {
                KeyToReturn = live_key_1
            }
            if (flavor.name == "two") {
                KeyToReturn = live_key_2
            }
        }
    }
    printout("KeyToReturn:" + KeyToReturn)
    return KeyToReturn
}

我在我的android.defaultConfig中有这个配置

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 23
    versionCode getVersionCode1()
    versionName getVersionName1() + ""
    manifestPlaceholders = [key: getKey()]
}

这是我AndroidManifest.xml相关部分的内容。
<meta-data
            android:name="key"
            android:value="${key}"/>

问题在于当我查看构建后的AndroidManifest.xml文件时,${key}值为空字符串。如何正确填充此值?
1个回答

9

您可以通过将占位符添加到适当的闭包中,根据产品风格(和我所知道的构建类型)定义清单占位符。

此示例应用程序中,我使用产品风格来使用不同的规则 Android 7.0 的网络安全配置

productFlavors {
    thawte {
        resValue "string", "app_name", "CA Validation Demo"
        applicationId "com.commonsware.android.downloader.ca.thawte"
        manifestPlaceholders=
                [networkSecurityConfig: 'network_thawte']
        buildConfigField "String", "URL", WARES
    }
    verisign {
        resValue "string", "app_name", "Invalid CA Validation Demo"
        applicationId "com.commonsware.android.downloader.ca.verisign"
        manifestPlaceholders=
                [networkSecurityConfig: 'network_verisign']
        buildConfigField "String", "URL", WARES
    }
    system {
        resValue "string", "app_name", "System CA Validation Demo"
        applicationId "com.commonsware.android.downloader.ca.system"
        manifestPlaceholders=
                [networkSecurityConfig: 'network_verisign_system']
        buildConfigField "String", "URL", WARES
    }
    pin {
        resValue "string", "app_name", "Cert Pin Demo"
        applicationId "com.commonsware.android.downloader.ca.pin"
        manifestPlaceholders=
                [networkSecurityConfig: 'network_pin']
        buildConfigField "String", "URL", WARES
    }
    invalidPin {
        resValue "string", "app_name", "Cert Pin Demo"
        applicationId "com.commonsware.android.downloader.ca.invalidpin"
        manifestPlaceholders=
                [networkSecurityConfig: 'network_invalid_pin']
        buildConfigField "String", "URL", WARES
    }
    selfSigned {
        resValue "string", "app_name", "Self-Signed Demo"
        applicationId "com.commonsware.android.downloader.ca.ss"
        manifestPlaceholders=
                [networkSecurityConfig: 'network_selfsigned']
        buildConfigField "String", "URL", SELFSIGNED
    }
    override {
        resValue "string", "app_name", "Debug Override Demo"
        applicationId "com.commonsware.android.downloader.ca.debug"
        manifestPlaceholders=
                [networkSecurityConfig: 'network_override']
        buildConfigField "String", "URL", SELFSIGNED
    }
}

我可以正常地在清单中引用该占位符:

<application
  android:icon="@drawable/ic_launcher"
  android:label="@string/app_name"
  android:networkSecurityConfig="@xml/${networkSecurityConfig}">

我有一个不同的值,它取决于是否为调试模式以及口味类型。我该如何同时考虑这两个因素? - Lena Bru
@LenaBru:就我所知,我不清楚。你在答案中概述的方法行不通。最好的情况是,所有构建变体都具有相同的值,其中该值将是您的循环处理的变体中的最后一个值。请理解build.gradle不会构建您的应用程序,而是构建了一个对象模型,该对象模型--几秒钟、几分钟或几小时后--构建了您的应用程序。因此,您的函数在循环中使用相同的N个构建变体进行评估N次。 - CommonsWare
一个库强制我在清单文件中处理元数据,而不是在代码中传递值,你说我真的无能为力吗?难道我需要创建独立的应用程序吗? - Lena Bru
1
@LenaBru:“你说我完全无能为力?”-- 我没有这么说。我是在说你问题中的方法行不通,而且我不知道如何在每个构建变体上操作manifestPlaceholders。在你的情况下,你不需要manifestPlaceholders--将你的值放在构建变体特定目录的字符串资源中(例如,oneDebug/res/values/strings.xml)。这让人想起了John O'Reilly的解决方案,只不过不是由Gradle生成的。 - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接