2016-02-08 16 views
9

我希望能夠從我們的CMS(或某個數據庫)的res/values/strings.xml中加載用戶可見字符串的值, gradle build。在Android Gradle版本中,在編譯期間更改strings.xml的內容

E.g.

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

可改爲

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

...或什麼的。

這個想法是,新的價值將被從我們的內容管理系統中讀取建設時間,然後將被烘烤到APK文件。 (動機是自動化應用程序字符串的更改,以便應用程序中的任何文本都將從現有的CMS中讀取)。

達到此目的的最佳方法是什麼?是否有可能在構建期間生成/修改資源文件(例如strings.xml),然後才由Android構建系統使用它們?


添加一些要求:

+1

簡單的方法:http://tools.android.com/tech-docs/new-build-system variant.resValue ...其他:建立自己的gradle插件... – Selvin

+0

謝謝Selvin,看起來很有前途。關於這個的一個問題是:我將如何去爲不同的語言提供回退值?這個功能可以嗎? – treesAreEverywhere

+0

'applicationVariants.all {variant - > variant.resValue「string」,「button_xxx」,「Here goes the text」}'...當然,您需要學習一些Groovy基礎知識(例如獲取這些值在線或從您特定的xml/json文件)... fx https://gist.github.com/SelvinPL/f89476b6585690cb252b ...我使用它來生成fx'colorPrimaryAX',它是colorPrimary和X%alpha https://gist.github .com/SelvinPL/8e673e38c5fed8e2132b – Selvin

回答

3

以下是您的字符串通過外部屬性文件進行修改的解決方案。不確定這完全符合你的要求,但它應該讓你開始。

我在構建中做了類似的事情 - 我有一些定製的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

+0

有趣的部分是...你如何將這個集成到構建過程中,也是如果你有不同的口味/構建類型,以及語言覆蓋? – treesAreEverywhere

+0

請參閱我的編輯 - 至於flavor/build類型,您可以輕鬆添加項目屬性並以這種方式有條件地更改字符串。我喜歡按照[這裏]所述使用它們(http://stackoverflow.com/questions/11696521/how-to-pass-arguments-from-command-line-to-gradle)。與語言相同,您的「cms.properties」可以包含您喜歡的任何語言。 – lase