19

我在 Android Studio 中用 gradle 制作了一个新应用,现在我需要制作大约 10 个版本,在资源中具有不同的包名称和值。我像示例一样制作了自定义风味,并希望用自定义值替换此自定义风味中的一些字符串。我找到了这样的例子:

filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: ['version': '2.2'])

但我不知道把它放在哪里。据我了解,我需要将其放入单独的任务中,但是如何使 IDE 调用此任务?

我还需要替换 Java 类和 Content Provider 的身份验证中的几个变量,也许我需要通过将文件复制到 flavor1 文件夹并让 gradle 合并它来做到这一点,但存储多个文件副本的方法似乎是错误的线...也许我需要为所有这些使用其他解决方案?

这是 build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4.2'
    }
}
apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':JazzyListView')
    compile project(':ABS')
    compile project(':Volley')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        versionCode 5
        versionName "3.0"
        minSdkVersion 8
        targetSdkVersion 17
    }

    sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
            java.srcDirs = ['src/main/java']
            res.srcDirs = ['src/main/res']
        }
    }

    productFlavors {
        flavor1 {
            packageName "com.example.flavor1"               
        }

        flavor2 {
            packageName "com.example.flavor2"
        }

    }

}
4

4 回答 4

18

我有一个类似的问题。我想将 Jenkins 内部版本号添加到从 strings.xml 合并的字符串中。这是我从 Android Gradle 插件 0.12.+ 开始的解决方案。

// Insert the build number into strings.xml
android.applicationVariants.all{ variant ->
    variant.mergeResources.doLast{
        ext.env = System.getenv()
        def buildNumber = env.BUILD_NUMBER
        if (buildNumber != null) {
            File valuesFile = file("${buildDir}/intermediates/res/${variant.dirName}/values/values.xml")
            println("Replacing revision number in " + valuesFile)
            println("Build number = " + buildNumber)
            String content = valuesFile.getText('UTF-8')
            content = content.replaceAll(/devBuild/, buildNumber)
            valuesFile.write(content, 'UTF-8')
        }
    }
}

您可能希望根据您想要执行的操作挂钩到不同的 Gradle 任务。查看作为 Android 构建一部分的任务来解决这个问题。

http://tools.android.com/tech-docs/new-build-system/user-guide

更新:在某些时候,Android Gradle 插件改变了从eachall迭代应用程序变体关键字的方式。我的答案已更新以反映更改,但如果此代码未将任何内容打印到控制台,请尝试切换到每个。

于 2013-07-24T16:56:55.223 回答
4

我试图获得与 Maven 资源过滤类似的功能。这就是我想出的。我的解决方案可以使用一些更健壮的更改(即从属性文件中提取等)。

我的示例仅显示了如何替换单个值,这就是我所需要的。变量遵循${some.property}约定。此解决方案还适用于具有自己的资源文件的产品风格。

import org.apache.tools.ant.filters.*
...
android.applicationVariants.all{ variant ->
    // Perform resource filtering
    variant.mergeResources.doLast {
        filterResources(variant)
    }
}

def filterResources(buildVariant) {

    //Setup temp directory to filter the resources
    File resFiltered = file("${buildDir}/res/all/filtered/${buildVariant.dirName}")
    if(resFiltered.exists()){
        resFiltered.delete()
    }

    //Copy and filter the resources.
    copy {
        from(buildVariant.processResources.resDir) {
            include '**/*.xml'

            //Could be improved upon to pull from a properties file, etc.
            ant.properties['app.version'] = project.version

            filter(ExpandProperties, project: ant.project)

        }
        from(buildVariant.processResources.resDir) {
            exclude '**/*.xml'
        }

        into resFiltered

    }

    //Delete all the original resource files
    file(buildVariant.processResources.resDir).deleteDir()
    //Replace with the filtered ones.
    resFiltered.renameTo(file(buildVariant.processResources.resDir))
    //Delete the original 'filtered' directory
    file( "${buildDir}/res/all/filtered").deleteDir()
}

strings.xml 中的示例

 ...
 <string name="app_version">${app.version}</string>
 ...
于 2014-05-08T20:36:27.553 回答
3

这些链接可能会有所帮助:

我的过滤器定义使用正则表达式来替换一些东西:

from('res/') {
    include '**/*.xml'
    filter {
        line -> line.replaceAll(/YOUR_REGEX_TO_REPLACE_SOMETHING/, 'REPLACED_RESULT_EXPRESSION')
    }
}
into 'build/path/to/your/filtered/resources/'
于 2013-06-26T03:54:48.103 回答
2

在“src”文件夹中,创建与“main”文件夹具有相同层次结构的“flavor1”和“flavor2”文件夹。如果您的 main/res/values 中有 strings.xml,您也可以在 flavor1/res/values 中执行此操作,并在其中包含替换值。它可能会在 IDE 中显示错误,但仍应构建并运行。

于 2013-06-25T15:11:36.487 回答