在Android gradle构建中,在构建过程中更改strings.xml的内容

在Android gradle构建中,在构建过程中更改strings.xml的内容,android,gradle,android-resources,Android,Gradle,Android Resources,我希望能够在gradle构建期间从CMS(或一些DB)的res/values/strings.xml加载用户可见字符串的值 例如 好的,开始吧 可以改成 <string name="button_label">OK, do it now!</string> 好的,现在就做! 。。。或者别的什么 其想法是,新值将在构建时从我们的CMS中读取,然后烘焙到APK文件中。(其动机是自动更改应用程序字符串,以便从现有CMS读取应用程序中的任何文本) 实现这一目标的最佳方式是什

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

例如

好的,开始吧
可以改成

<string name="button_label">OK, do it now!</string>
好的,现在就做!
。。。或者别的什么

其想法是,新值将在构建时从我们的CMS中读取,然后烘焙到APK文件中。(其动机是自动更改应用程序字符串,以便从现有CMS读取应用程序中的任何文本)

实现这一目标的最佳方式是什么?在Android构建系统使用资源文件之前,是否可以在构建过程中生成/修改资源文件(例如strings.xml)


增加一些其他要求:

  • 解决方案需要支持“替代资源”,即覆盖其他语言的字符串。()
  • 解决方案应该能够覆盖原始(默认)strings.xml文件中的值

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

我在我的构建中也做了类似的事情——我有一些自定义的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)
    }
}

然后,您的gradle命令可能看起来像
gradleupdatestringsxml assembleerelease

简单的方法:variant.resValue。。。其他:构建自己的gradle插件…谢谢Selvin,这看起来很有希望。但有一个问题是:我将如何为不同的语言提供回退值?这个函数可以吗?
applicationVariants.all{variant->variant.resValue“string”,“button_xxx”,“下面是文本”}
。。。当然,您需要学习一些Groovy基础知识(例如,在线获取这些值或从特定的xml/json文件获取这些值)。。。外汇。。。我用它来生成fx
colorPrimaryAX
,这是带有X%alpha的colorPrimary,还有两个问题。。。您不能覆盖这些值。。。因此,如果您的res文件夹中已经有
按钮\u xxx
,您就不能将其与resValue一起使用…我指的是“语言”。。这里定义的“语言资源限定符”:有趣的部分是。。。如果您有不同的风格/构建类型以及语言覆盖,如何将其集成到构建过程中?请参阅我的编辑-对于风格/构建类型,您可以轻松地添加项目属性并以这种方式有条件地更改字符串。我喜欢按描述使用它们。与语言一样,您的“cms.properties”可以包含您喜欢的任何语言。
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)
    }
}
apply from: "common.gradle"
task updateStringsXml() {
    doFirst {
        updateStrings()
    }
}