Android构建渐变-替换字符串资源值



我有一个特殊情况,在使用Jenkins构建时,我需要覆盖谷歌地图关键字字符串变量。我设置了一个特殊的结构,像这样:

  • 调试
    • res
        • google_maps_api.xml
  • 主要
    • res
        • google_maps_api.xml

因此,在mainres文件中,我放入了发布API密钥,在
调试res文件中放入了调试API密钥(对于我正在工作的机器-为Android的debug.keystore生成)。

在构建gradle文件中,我有以下基本逻辑,用于根据Jenkins环境中的设置创建字符串资源:

String googleMapApiKey = System.env.MAP_API_KEY;
...
android {
...
buildTypes {
...
debug {
if (null != googleMapApiKey && !googleMapApiKey.equals("null")) {
resValue "string", "google_maps_key", googleMapApiKey
}
}
...
}
...
}

xml文件包含以下内容:

<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
MY_DEBUG_API_KEY
</string>

我知道这个问题是因为字符串资源的preserve标志,但如果删除它,事情就有可能变得一团糟,导致字符串资源丢失。有没有一种方法可以替换实际字符串资源的值,而不仅仅是在构建渐变文件中创建一个新的值?

我只是想,当我使用Jenkins环境中的值时,解决方案也可以是排除该文件,但我不知道它是否适用于android gradle系统。有人知道这是否可行且更重要吗?

LE:

我似乎不得不将res文件从main文件夹移到release中。因此,我现在有以下结构:

  • 调试
    • res
        • google_maps_api.xml
  • 释放
    • res
        • google_maps_api.xml

目前,它似乎是这样工作的

LLE:上面的方法不起作用,我很快就得出了结论。似乎仍然使用xml文件中的值,即使我在gradle脚本中声明了相同的值(至少作为名称)。

作为解决方法,我实现了以下逻辑:

  • 我从版本文件夹中删除了google_maps_api.xml
  • 我创建了一个自定义方法,它从local.properties:加载一个属性

    /**
    * Get Google Map API Key which should be used by google map services.
    * <br/>
    * Note that this key should not be used when an key is available from Jenkins as most probably debug.keystore is
    * different than the one on your machine.
    *
    * @return the value of your local Google Map API Key
    */
    def getLocalGoogleMapApiKey() {
    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())
    def localMalKey = properties.getProperty('google.map.apiKey')
    if (localMalKey == null) {
    // Throw an exception if the property wasn't setup for this
    throw new GradleException(
    "Google Map API Key property not found. Define your debug Google Map API Key [google.map.apiKey] in " +
    "your local.properties file! E.g.: google.map.apiKey=YOUR_GOOGLE_MAP_API_KEY")
    }
    return localMalKey
    }
    
  • 我在local.properties文件中添加了以下属性

    google.map.apiKey=MY_API_KEY
    
  • 我在build.gradle中添加了以下逻辑:

    ...
    // Google Map API Key - from Jenkins or from local
    String googleMapApiKey = System.env.MAP_API_KEY ?: getLocalGoogleMapApiKey();
    ...
    android {
    ...
    buildTypes {
    ...
    debug {
    /* Create a string resource which will be used in AndroidManifest.xml file (from Jenkins or local)*/
    resValue "string", "google_maps_key", googleMapApiKey
    println(">>>>>>>>> Google Map API Key: " + googleMapApiKey)
    }
    ...
    }
    ...
    }
    

我之所以选择这个解决方案,是因为以下原因:

  • 每个用户都可以设置自己的API KEY进行调试(local.properties文件不会影响其他开发人员,因为它永远不会进入存储库)
  • Jenkins可以在任何时候更改它的密钥,而不会影响项目或任何开发人员
  • 没有必要改变项目的结构或打乱项目的资源
  • 任何人都可以安全地使用该方法,如果任何人没有正确设置该属性,它将抛出一个很好的错误

我希望这能帮助其他有类似问题的人:

最新更新