我有一个特殊情况,在使用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可以在任何时候更改它的密钥,而不会影响项目或任何开发人员
- 没有必要改变项目的结构或打乱项目的资源
- 任何人都可以安全地使用该方法,如果任何人没有正确设置该属性,它将抛出一个很好的错误
我希望这能帮助其他有类似问题的人: