Можно ли определить ресурс массива Android в Gradle?

В Gradle для Android я пытаюсь создать эквивалент этого ресурса массива строк...

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

... в файле конфигурации приложения build.gradle. Я не хочу жестко задавать эти значения в res/values ​​/arrays.xml, так как я хочу иметь возможность генерировать различное содержимое массива для разных вариантов сборки (dev vs. prod). Я знаю, что есть обходные пути, но это было бы самым чистым решением, если это возможно.

Я пробовал такие вещи, как выдержка ниже, с типом resValue "string-array" или "array", но я получаю сообщение об ошибке, поскольку resValue() не существует. Конечно, параметр типа resValue для "string" работает для одиночных строк, но мне нужно создать ресурс массива строк.

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

Документация Gradle для Android не помогает. Он перечисляет этот метод...

void resValue (тип строки, имя строки, значение строки)

... но это не указывает допустимые значения для параметра param. У него просто есть ссылка, которая гласит: См. Типы ресурсов", но это просто указывает на обычные документы Android для типов ресурсов и не описывает, как выразить их в Gradle Android DSL.

Есть ли у кого-нибудь указания? Я просматривал онлайн и ничего не нашел.

Ответ 1

Здесь ближайший я получил с помощью @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

Затем вы можете переопределить значение buildConfigField для типа buildType. Таким образом, если вам это не нужно специально, чтобы быть в R.array. *, Это будет отвечать вашим потребностям. Оставляя это открытым пока, если кто-то еще знает, как это сделать с resValue.

Ответ 2

Другое решение будет работать. но я обнаружил, что он не будет работать с другими файлами конфигурации сборки, такими как BUCK

вы также можете просто иметь длинную статическую URL-строку, содержащую все URL-адреса, но разделенные запятыми (или разделенные каким-либо другим разделителем). то во время выполнения u зачитывает значение, разделяет его запятой.

Ответ 3

Чтобы иметь возможность создавать массив через resValue, вы можете хранить все элементы массива внутри тега item. Поэтому вы должны написать в gradle что-то вроде этого:

resValue('array', 'ver_2_skus', "<item>sku1</item><item>sku2</item>")

Но есть ужасная ошибка - все символы < записываются в res как &lt;. Я провожу некоторое время, чтобы узнать, как написать < с помощью gradle, но не удалось. Поэтому я сделал один взлом - я заменил < на некоторую строку, а затем, после сборки, заменил ее на <. Я ненавижу этот хак, может быть, я что-то пропустил, но он работает. Вот код, который вы должны положить в конец gradle script (да, код должен дублироваться для работы).

  • При создании массива res замените все < на некоторую строку, т.е. IWANTTOREPLACEITWITHLEFTARROW:
resValue('array', 'ver_2_skus', "IWANTTOREPLACEITWITHLEFTARROWitem>sku1IWANTTOREPLACEITWITHLEFTARROW/item>IWANTTOREPLACEITWITHLEFTARROWitem>sku2IWANTTOREPLACEITWITHLEFTARROW/item>")
  1. Добавьте это в конец файла gradle:
android.applicationVariants.all { variant ->
    println("variant: "+variant.dirName)
    variant.mergeResources.doLast {
        try {
            println("3")
            ext.env = System.getenv()
            File valuesFile = file("${buildDir}/intermediates/res/merged/${variant.dirName}/values/values.xml")
            String content = valuesFile.getText('UTF-8')
            content = content.replaceAll(/IWANTTOREPLACEITWITHLEFTARROW/, '<')
            valuesFile.write(content, 'UTF-8')
        } catch (Exception e) {
            println("Exception = " + e)
        }
    }

    try {
        println("try")
        ext.env = System.getenv()
        File valuesFile = file("${buildDir}/intermediates/res/merged/${variant.dirName}/values/values.xml")
        String content = valuesFile.getText('UTF-8')
        content = content.replaceAll(/IWANTTOREPLACEITWITHLEFTARROW/, '<')
        valuesFile.write(content, 'UTF-8')
    } catch (Exception e) {
        println("Exception = " + e)
    }
}

Ответ 4

Определение строки [] адресов в BuildConfig:

productFlavors {
    prod {
       ext.centralUrls = ["http://www.url1.com", "http://www.url2.com", "http://www.url3.com"]
    }
    ...
}

buildConfigField("String[]", "CENTRAL_URLS", '{' + variant.productFlavors.get(0).ext.centralUrls.collect {"\"${it}\""}.join(",")  + '}')