【问题标题】:define manifest place holders in build.gradle在 build.gradle 中定义清单占位符
【发布时间】:2016-12-01 12:49:01
【问题描述】:

我的 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} 值是一个空字符串。

如何正确填充此值?

【问题讨论】:

    标签: android android-gradle-plugin


    【解决方案1】:

    您可以根据产品风格(和 AFAIK 构建类型)定义清单占位符,方法是将它们添加到适当的闭包中。

    this sample app 中,我使用产品风格为Android 7.0 的network security configuration 使用不同的规则:

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

    【讨论】:

    • 我有一个不同的值,这取决于它是否是调试,以及风味类型。我如何兼顾两者?
    • @LenaBru:我不知道。您在答案中概述的方法将不起作用。充其量,您对于所有构建变体将具有相同的值,其中该值将是您循环处理的最后一个变体。请理解build.gradle 不会构建您的应用程序,而是构建build.gradle 中的对象模型。该对象模型(几秒、几分钟或几小时后)构建您的应用程序。因此,您的函数会在循环中使用相同的 N 个构建变体进行 N 次评估。
    • 一个库迫使我使用清单文件中的元数据,而不是在代码中传递值,你说我绝对无能为力?我需要单独的应用程序吗?
    • @LenaBru:“你说我绝对无能为力?” - 我没那么说过。我说你的问题中的方法不起作用,我不知道如何在每个构建变体的基础上操作manifestPlaceholders。在您的情况下,您不需要manifestPlaceholders - 将您的值放在特定于构建变体的目录中的字符串资源中(例如,oneDebug/res/values/strings.xml)。这让人想起 John O'Reilly 的解决方案,只是不是从 Gradle 生成的。
    猜你喜欢
    • 2016-10-02
    • 2021-01-12
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2013-12-12
    • 2012-01-07
    • 1970-01-01
    相关资源
    最近更新 更多