在Android gradle构建中,在构建期间更改strings.xml的内容

时间:2016-02-08 15:00:43

标签: android gradle android-resources

我希望能够在gradle构建期间从我们的CMS(或某些数据库)加载res / values / strings.xml中的用户可见字符串的值。

E.g。

<string name="button_label">OK, do it</string>

可以更改为

<string name="button_label">OK, do it now!</string>

......或其他什么。

我们的想法是从我们的CMS中读取新值,然后将被纳入APK文件。 (目的是自动更改应用程序字符串,以便从现有CMS中读取应用程序中的任何文本。)

实现这一目标的最佳方法是什么?是否有可能在构建期间生成/修改资源文件(例如strings.xml),就在它们被Android构建系统使用之前?

添加更多要求:

1 个答案:

答案 0 :(得分:4)

这是一个通过外部属性文件修改字符串的解决方案。不确定这完全符合您的要求,但它应该让您开始。

我在构建中做了类似的事情 - 我有一些自定义的gradle任务,在doFirst()内部调用了这种类型的替换。这里的正则表达式可能会使用一些抛光,输入格式可能会根据您的要求而改变,但在一些本地测试中,这似乎对我有用。

ext.updateStrings = {
println("Changing strings!")
Properties props = new Properties()
props.load(new FileInputStream(file('cms.properties')))
def stringsFile = file("src/main/res/values/strings.xml")
def stringsText = stringsFile.getText()
for (p in props) {
    def pattern = Pattern.compile(String.format("%s\">.*<", p.key));
    def match = pattern.matcher(stringsText);
    match.find();
    println("found key " + p.key + ", replacing string with " + p.value)
    stringsText = match.replaceAll(String.format("%s\">%s<", p.key, p.value))
    stringsFile.write(stringsText)
    }
}

我将外部属性/函数保存在单独的文件中(例如common.gradle)。在build.gradle中,您可以添加如下自定义任务:

apply from: "common.gradle"
task updateStringsXml() {
    doFirst {
        updateStrings()
    }
}

然后,您的gradle命令可能看起来像gradle updateStringsXml assembleRelease