【问题标题】:Android build gradle - replace string resource valueAndroid build gradle - 替换字符串资源值
【发布时间】:2016-09-24 14:46:15
【问题描述】:

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

  • 调试
    • 资源
        • google_maps_api.xml
  • 主要
    • 资源
        • google_maps_api.xml

因此,在 ma​​in res 文件中,我放置了发布 API 密钥,在 debug res 文件中,我放置了调试 API 密钥(对于我正在工作的机器on - 为 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>

我知道问题出在字符串资源的保留标志上,但如果删除它,则有可能会搞砸并丢失该字符串资源。 有没有办法可以替换实际字符串资源的值,而不仅仅是在构建 gradle 文件中创建一个新的?

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

LE:

看来我不得不将 ma​​in 文件夹中的 res 文件移动到 release 文件夹中。因此我现在有以下结构:

  • 调试
    • 资源
        • google_maps_api.xml
  • 发布
    • 资源
        • google_maps_api.xml

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

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

【问题讨论】:

    标签: android string gradle replace resources


    【解决方案1】:

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

    • 我从 release 文件夹中删除了 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 可以随时更改密钥,而不会影响项目或任何开发人员
    • 无需更改项目结构或弄乱它的资源
    • 任何人都可以安全使用该方法,如果有人没有正确设置属性,它会抛出一个很好的错误

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-10
      相关资源
      最近更新 更多