使用gradle将strings.xml中的单词替换为buildType

时间:2016-11-28 11:57:17

标签: android gradle preprocessor

我有一个有多个本地化的项目 现在我必须替换所有strings.xml文件中的某个单词以获取不同的buildType。例如,假设我有这个:

<string>My name is Bill</string>
<string>Bill is on duty today</string>

在另一个buildType中我需要

<string>My name is Will</string>
<string>Will is on duty today</string>

我该怎么做(可能通过Gradle)?

7 个答案:

答案 0 :(得分:3)

好的,找到正确的解决方案,它不是解决方法: 对于所需的buildType,请添加以下内容

    applicationVariants.all { variant ->
    variant.mergeResources.doLast {
        def dir = new File("${buildDir}/intermediates/res/merged/${variant.dirName}")  //iterating through resources, prepared for including to APK (merged resources)
        println("Resources dir " + dir)
        dir.eachFileRecurse { file ->
            if(file.name.endsWith(".xml")) { //processing only files, which names and with .xml
                String content = file.getText('UTF-8')
                if(content != null && content.contains("Bill")) {
                    println("Replacing name in " + file)
                    content = content.replace("Bill", "Will")  //replacing all Bill words with Will word in files
                    file.write(content, 'UTF-8')
                }

            }
        }
    }

答案 1 :(得分:2)

您可以在build.gradle中执行以下操作,但仅适用于该特定字符串资源。

resValue "string", "<string_name>", string_value

答案 2 :(得分:1)

这里的答案不再适用于最新的android构建工具,但这是一个对我有用的新版本。

android.applicationVariants.all { variant ->
    variant.mergeResources.doFirst {
         variant.sourceSets.each { sourceSet ->
            sourceSet.res.srcDirs = sourceSet.res.srcDirs.collect { dir ->
                def relDir = relativePath(dir)
                copy {
                    from(dir)
                    include '**/*.xml'
                    filteringCharset = 'UTF-8'
                    filter {
                        line -> line
                                .replace('Bill', 'Will')
                    }
                    into("${buildDir}/tmp/${variant.dirName}/${relDir}")
                }
                copy {
                    from(dir)
                    exclude '**/*.xml'
                    into("${buildDir}/tmp/${variant.dirName}/${relDir}")
                }
                return "${buildDir}/tmp/${variant.dirName}/${relDir}"
            }
        }
    }
}

答案 3 :(得分:0)

使用app的build.gradle(模块,而不是项目)在目录中创建文件gradle.properties。在这个应用程序的地方字符串 GOOGLE_MAPS_API_KEY = ishufhiaushdiasdh

添加字段&#39; buildConfigField&#39;在buildTypes部分的build.gradle文件中。它看起来像:

buildTypes {
        debug {
            buildConfigField "String", "GOOGLE_MAPS_API_KEY", String.format("\"%s\"", GOOGLE_MAPS_API_KEY)
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            buildConfigField "String", "GOOGLE_MAPS_API_KEY", String.format("\"%s\"", GOOGLE_MAPS_API_KEY)
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

编译项目后,您将在BuildConfig类中找到生成的值作为静态字符串。

答案 4 :(得分:0)

为什么不使用动态字符串格式:

<string name="my_message">%1$s is on duty today</string>

在一个构建变体中:

<string name="name">Bill</string>

在另一个构建版本中:

<string name="name">Will</string>
你的代码中的

String text = String.format(getResources().getString(R.string.my_message), getResources().getString(R.string.name));

答案 5 :(得分:0)

一种解决方案虽然不适用于所有情况,但是使用Copy任务和filter指令:

task replace (type: Copy) {
   from "sources" {
      include "srcStrings.xml"
      filter { line -> line.replaceAll("Will", "Bill") }
   }
   into "strings.xml"
}

答案 6 :(得分:0)

处理行时,应观察用replace()replaceAll()获得的结果。并考虑到要处理的文件的绝对目录存在(不一定在res.srcDirs中)

sourceSets {
    flavor {

        println res.srcDirs

        task testA() {

            def relativeDirFile = 'src/flavor/res'
            def file = "${relativeDirFile}/values/strings.xml"
            def absoluteDirFile = "${rootDir}/module/${file}"

            def buildDirToCopy = "${buildDir}/tmp/${relativeDirFile}/values"

            copy {
                    from(absoluteDirFile)
                    filter {
                        String line ->
                            println line

                            line.replace("(.*)", line)  // To keep the line
                            // OR
                            line.replaceAll("(.*)", "") // To erase the line
                    }
                    into(buildDirToCopy)
            }

            res.srcDirs += (buildDirToCopy + "/strings.xml")
            
            // Check the directories that were included in the flavor.
            println res.srcDirs
        }

    }
}

最后,您可以extract the task进入另一个gradle文件


我还建议深化使用regex

GL