根据buildType使用gradle覆盖资源

我想重写res / strings.xml中的一些string与gradle

我知道, 因为Android的Gradle插件0.7。+ theres的可能性有一个变体特定的源文件夹。 但我的应用程序有很多味道,我不想额外添加变体特定的文件夹。

更新2014-01-17

我想要的细节:

我的资源中有一些variables只依赖于buildType(例如“release”)。 首先,我认为我的SOLUTION_1 (覆盖资源合并后的数据)是很好的,因为如果我必须改变这些variables,我只需要在build.config(只是一个地方)中改变它们。 但正如Scott Barta在下面的评论中所写的那样,这个解决scheme并不是一个好主意。

所以我尝试了另一个解决schemeSOLUTION_2 (只是合并正确的资源)基于这个shakalaca GitHub项目 。 我认为这种方式更优雅,我仍然有优势,只是在一个地方改变variables!

SOLUTION_1(覆盖资源合并后的数据):

我在AS 0.4.2中做了什么:

  • build.gradle我尝试重写string“Hello World”到“OVERRIDE”( 根据我的回答在这个职位 ):

     android.applicationVariants.all{ variant -> // override data in resource after merge task variant.processResources.doLast { overrideDataInResources(variant) } } def overrideDataInResources(buildVariant){ copy { // *** SET COPY PATHS *** try { from("${buildDir}/res/all/${buildVariant.dirName}") { // println "... FROM: ${buildDir}/res/all/${buildVariant.dirName}" include "values/values.xml" } } catch (e) { println "... EXCEPTION: " + e } into("${buildDir}/res/all/${buildVariant.dirName}/values") // println "... INTO: ${buildDir}/res/all/${buildVariant.dirName}/values" // --- override string "hello_world" filter { String line -> line.replaceAll("<string name=\"hello_world\">Hello world!</string>", "<string name=\"hello_world\">OVERRIDE</string>"); } // *** SET PATH TO NEW RES *** buildVariant.processResources.resDir = file("${buildDir}/res/all/${buildVariant.dirName}/values/values/values.xml") // println "... NEW RES PATH: " + "${buildDir}/res/all/${buildVariant.dirName}/values/values/values.xml" } } 

复制和过滤任务工作正常,但我不能将“新”values.xml设置为string资源。

SOLUTION_2(只需合并正确的资源)

  • 为特定的buildType定义一个floavor(例如“releaseRes”)
  • 将这些资源与您想要build立的风味合并:

     android.applicationVariants.all{ variant -> variant.mergeResources.doFirst{ checkResourceFolder(variant) } } def checkResourceFolder(variant){ def name = variant.name; if(name.contains("Release")){ android.sourceSets.release.res.srcDirs = ['src/releaseRes/res'] android.sourceSets.flavor1.res.srcDirs = ['src/flavor1/res'] } } 

Solutions Collecting From Web of "根据buildType使用gradle覆盖资源"

您应该努力想出一个解决scheme,不涉及在构build文件中编写任何自定义代码,特别是在dynamic重新指派源代码集时会执行一些棘手问题的代码。 自定义的Gradle代码有时候写得很难,而且很难debugging和维护。 新的构build系统非常强大,已经具有很大的灵活性,很可能你已经可以做你想做的事了; 这只是一个学习如何的问题。

特别是如果你只是在学习Android-Gradle项目的细节(而且它是如此的新颖以至于我们都是),那么最好尽量使用系统内置的function,然后再去思考。

一些build议:

  • 您不太可能需要根据构buildtypes来改变资源。 Android-Gradle中的构buildtypes应该是类似debugging或发布的types,其差别在于可debugging性,编译器优化或签名; 构buildtypes应该是function上相同的。 如果您查看可以通过Groovy DSL设置构buildtypes的属性 ,您可以看到intent: debuggablejniDebugBuildsigningConfigzipAlignpackageNameSuffixversionNameSuffixsigningConfigzipAlignrunProguardproguardFileproguardFiles
  • 如果您仍然认为您想要根据构buildtypes来改变资源,那么使用当前的构build系统已经有了一个简单的方法。 您可以拥有一个特定于构buildtypes的资源目录,将资源放在那里,构build系统中的资源合并将在构build时为您处理。 这是Android / Gradle中的强大function之一。 请参阅使用构build版本 – 正确地构造源文件夹和构build版本库以获取有关如何完成此工作的信息。
  • 如果您想根据构buildtypes来改变某些内容,并且您的需求非常快速简单,那么您可能需要在Java代码中进行切换,而不是使用资源,而不是在构build系统中进行切换。 有这样的BuildConfig机制 – 它是一个Java类,它定义了一个基于debug / release构build状态的DEBUG标志,并且可以从不同的构buildtypes添加自己的定制Java代码来做更有意义的事情。 BuildConfig旨在允许构buildtypes之间的function差别较小,例如debugging构build可能需要执行一些浪费的操作来协助开发,如进行更多的数据validation或创build更详细的debugging日志logging,以及最佳的浪费没有发布版本。 话虽如此,这可能是一个合适的机制去做你想做的事情。
  • 现在考虑使用风格来为你正在使用的构buildtypes。 从概念上来说,一种风格就像一个构buildtypes,它是你的应用程序的另一个可以构build的变体; 构build系统将创build一个风格与构buildtypes的matrix,并可以构build所有组合。 然而,口味处理不同的用例,不同的口味共享大多数代码,但是可能具有显着的function差异。 一个常见的例子是你的应用程序的免费版本和付费版本。 由于您的应用程序的不同变体中的不同资源表示不同的function,这可能表示需要不同的风格。 Flavors可以拥有不同的资源目录,这些资源目录在构build时与Buildconfiguration相同; 看到更多的信息上面链接的问题。

我不相信你需要定制构build脚本来达到你想要的。 根据我的阅读http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants ; 当构build运行时,资源将从以下文件夹合并(如果存在);

 src/[flavour][buildType]/res src/[buildType]/res src/[flavour]/res src/main/res 

所以我相信你可以通过在src / release / res中简单地添加资源来实现你想要的。

尽pipe你可以通过指定相关的sourceSets来调整文件夹名称,如果你真的想要改变它们的话,可以调整[type] .res.srcDirs。

如果有人偶然发现这一点

  buildTypes { debug{ buildConfigField "String", "Your_string_key", '"yourkeyvalue"' buildConfigField "String", "SOCKET_URL", '"some text"' buildConfigField "Boolean", "LOG", 'true' } release { buildConfigField "String", "Your_string_key", '"release text"' buildConfigField "String", "SOCKET_URL", '"release text"' buildConfigField "Boolean", "LOG", 'false' } } 

并使用构build变体来访问这些值:

  if(!BuildConfig.LOG) // do something with the boolean value 

要么

 view.setText(BuildConfig.yourkeyvalue);