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

tre*_*ere 9 android gradle android-resources

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

例如

<string name="button_label">OK, do it</string>
Run Code Online (Sandbox Code Playgroud)

可以改为

<string name="button_label">OK, do it now!</string>
Run Code Online (Sandbox Code Playgroud)

... 管他呢.

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

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


添加更多要求:

las*_*ase 5

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

我在我的构建中做了一些类似的事情 - 我有一些自定义的 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

apply from: "common.gradle"
task updateStringsXml() {
    doFirst {
        updateStrings()
    }
}
Run Code Online (Sandbox Code Playgroud)

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