Is it possible to define an Android string-array resource in Gradle?

时间:2016-07-11 21:32:39

标签: java android gradle android-gradle build.gradle

In Gradle for Android, I'm trying to generate the equivalent of this string-array resource...

<resources>
    <string-array name="url_array">
       <item>http://www.url1.com</item>
       <item>http://www.url2.com</item>
       <item>http://www.url3.com</item>
    </string-array>
</resources>

...in my app's build.gradle config file. I don't want to hardcode these values in res/values/arrays.xml, since I want to be able to generate different array contents for different build variants (dev vs. prod). I know there are workarounds, but this would be the cleanest solution if it's possible.

I've tried things like the excerpt below with a resValue type of "string-array" or "array", but I get an error saying resValue() doesn't exist. Of course, a resValue type param of "string" works for single strings, but I need to generate a string array resource.

resValue "string-array", "url_array",
   ["http://www.url1.com",
    "http://www.url2.com",
    "http://www.url3.com"]

The Gradle for Android documentation doesn't help. It lists this method...

void resValue(String type, String name, String value)

...but it doesn't indicate the valid values for the type param. It simply has a link that says "See Resource Types" but that just points to the regular Android docs for resource types and doesn't describe how to express them in the Gradle Android DSL.

Does anyone have any guidance? I've looked all over online and haven't found anything.

4 个答案:

答案 0 :(得分:12)

这是我得到的最接近的@schwiz的指导。我仍然无法使用resValue找到一种方法,但是可以定义一个可以实现相同目标的 buildConfigField

buildConfigField "String[]", "URL_ARRAY",
        "{" +
                "\"http://www.url1.com\"," +
                "\"http://www.url2.com\"," +
                "\"http://www.url3.com\"" +
                "}"

这使您可以通过BuildConfig访问该数组:

public static final String[] URL_ARRAY = {
   "http://www.url1.com",
   "http://www.url2.com",
   "http://www.url3.com"}; // whitespace added for clarity

然后,您可以覆盖每个buildType的buildConfigField值。因此,除非您特别需要在R.array。*中,否则这将满足您的需求。暂时保持开放以防其他人知道如何使用resValue执行此操作。

答案 1 :(得分:2)

在BuildConfig中定义Urls的String []:

android {

    ...

    def tests1 = ["url-a1", "url-b1", "url-c1"]

    ext {
        tests2 = ["url-a2", "url-b2", "url-c2"]
    }

    // Specifies one flavor dimension.
    flavorDimensions "default"

    productFlavors {
        devel {
            dimension 'default'
        }
    }

    //Default values for all productFlavors
    productFlavors.all {
        ext.tests3 = ["url-a3", "url-b3", "url-c3"]
    } 

    android.applicationVariants.all { variant ->

        buildConfigField("String[]", "TESTS1", '{' + tests1.collect {
            "\"${it}\""
        }.join(",") + '}')

        buildConfigField("String[]", "TESTS2", '{' + android.ext.tests2.collect {
            "\"${it}\""
        }.join(",") + '}')

        //TEST3 works only when is some Flavor defined 
        buildConfigField("String[]", "TESTS3", '{' + variant.productFlavors.get(0).ext.tests3.collect {
            "\"${it}\""
        }.join(",") + '}')
    }
}

答案 2 :(得分:1)

为了能够通过cat >> ~/.inputrc "\e[5~": history-search-backward "\e[6~": history-search-forward 创建数组,您应该将所有数组元素存储在resValue标记内。所以你应该用gradle写这样的东西:

item

但是有一个可怕的错误 - 所有resValue('array', 'ver_2_skus', "<item>sku1</item><item>sku2</item>") 符号都将res写为<。我花了一些时间来找到如何用gradle写&lt;但是失败了。所以我做了一个hack - 我用一些字符串替换<然后在构建之后用<替换它。我讨厌这个黑客,也许我想念一些东西,但它确实有效。以下是代码,您必须将其放在gradle脚本的末尾(是的,代码必须重复才能工作)。

  1. 创建res数组时,用一些字符串替换所有<,即<
  2. IWANTTOREPLACEITWITHLEFTARROW
    1. 将其添加到gradle文件的末尾:
    2. resValue('array', 'ver_2_skus', "IWANTTOREPLACEITWITHLEFTARROWitem>sku1IWANTTOREPLACEITWITHLEFTARROW/item>IWANTTOREPLACEITWITHLEFTARROWitem>sku2IWANTTOREPLACEITWITHLEFTARROW/item>")
      

答案 3 :(得分:0)

其他解决方案将有效。但我发现它不能与其他构建配置文件如BUCK

一起使用

你也可以只有一个长静态URL字符串,其中包含所有URL,但是以逗号分隔(或由其他分隔符分隔)。然后在运行时,你读出值,用逗号分隔它。