我正在尝试构建一个具有6种构建风格的Android项目。每个只有一个独特的资源文件。 Ant构建将文件从res / configs /复制到res / raw /以用于每种风格。我不想打破这个版本,我无法弄清楚如何让Gradle Android版本与这个文件夹结构一起使用。所以我添加了一个复制阶段来获取一个公共资源文件夹,然后添加一个用于每个风格的文件只有一个。
task cleanExtra(type: Delete) {
delete 'res-common'
delete 'res-dev'
delete 'res-qa'
delete 'res-sb'
delete 'res-test'
delete 'res-stage'
delete 'res-prod'
}
task setUpSharedResources(type: Copy) {
from 'res'
into 'res-common'
exclude '**/environment.properties'
}
task setUpDevResources(type: Copy ) {
from 'configs/dev/'
into 'res-dev/raw/'
}
task setUpQaResources(type: Copy ) {
from 'configs/qa/'
into 'res-qa/raw/'
}
task setUpSbResources(type: Copy ) {
from 'configs/sb/'
into 'res-sb/raw/'
}
task setUpTestResources(type: Copy ) {
from 'configs/test/'
into 'res-test/raw/'
}
task setUpStageResources(type: Copy ) {
from 'configs/stage/'
into 'res-stage/raw/'
}
task setUpProdResources(type: Copy ) {
from 'configs/prod/'
into 'res-prod/raw/'
}
然后将flavor复制任务设置为在preBuild之前运行
preBuild.dependsOn setUpDevResources
preBuild.dependsOn setUpQaResources
preBuild.dependsOn setUpSbResources
preBuild.dependsOn setUpTestResources
preBuild.dependsOn setUpStageResources
preBuild.dependsOn setUpProdResources
然后常见的复制任务取决于风味的任务,所以它首先发生
setUpDevResources.dependsOn setUpSharedResources
setUpQaResources.dependsOn setUpSharedResources
setUpSbResources.dependsOn setUpSharedResources
setUpTestResources.dependsOn setUpSharedResources
setUpStageResources.dependsOn setUpSharedResources
setUpProdResources.dependsOn setUpSharedResources
clean.dependsOn(cleanExtra)
创建了这些新的res文件夹后,我可以设置我的android源集和产品风格,如此
productFlavors {
dev {}
prod {}
qa {}
sb {}
stage{}
// test {}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['.apt_generated','src']
resources.srcDirs = ['.apt_generated','src']
aidl.srcDirs = ['.apt_generated','src']
renderscript.srcDirs = ['.apt_generated','src']
assets.srcDirs = ['assets']
}
dev {
res.srcDirs = ['res-common','res-dev']
}
prod {
res.srcDirs = ['res-common','res-prod']
}
qa {
res.srcDirs = ['res-common','res-qa']
}
sb {
res.srcDirs = ['res-common','res-sb']
}
stage {
res.srcDirs = ['res-common','res-stage']
}
test {
res.srcDirs = ['res-common','res-test']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
虽然这似乎有效,但它有一些问题。复制任务与口味无关。我只是硬编码文件夹名称。看起来应该有一些循环方式。或者甚至最好不要完成复制任务,只是告诉Gradle整齐地使用哪些文件。
另一件我不确定的事情。我没有创造一种测试味道,因为gradle抱怨那个已经存在。我不确定是否存在因为出于不同目的而劫持它的问题。
我得到的印象是我正在迫使Gradle为所有6种口味构建所有资源。有没有办法解决这个问题更清洁或更快是我的问题?
*跟进* 我意识到我可以通过适当的资源合并来避免复制阶段。我遇到了一些问题,这就是我做文件复制的原因。当我在两个资源文件夹中都有文件时,我收到此错误
/Users/mkluver/Documents/OH-android/oep/res/raw/environment_override.properties:
Error: Duplicate resources: /Users/mkluver/Documents/OH-android/oep/res/raw/environment_override.properties:raw/environment_override,
/Users/mkluver/Documents/OH-android/oep/res-dev/raw/environment_override.properties:raw/environment_override
我猜测资源合并失败了,因为这些不是XML资源而是属性文件。用。之类的行格式化。
#This is a comment
server.url=http://www.theserver.com/api
server.version=5.4
如何告诉gradle如何合并这些类型的文件?
答案 0 :(得分:22)
这太过分了。
你需要的只是:
src/main/res
这是您所有口味的共同资源
src/dev/res
这是dev
风格特有的资源。
src/prod/res
这是prod
风格特有的资源。
等...
注意:如果您在src/main/res
和src/<flavor>/res
都有资源,则flavor res文件夹中的资源将获胜。
每种风味实际上都会获得自己的res文件夹和src/main/res
没有必要手动复制东西,这一切都是为你完成的。其中一个优点是资源文件夹的复制/合并将以递增方式完成,这将更快,更有效。
您似乎正在使用res
而不是src/main/res
,因此您可能正在使用旧的旧文件夹结构。这不是问题,您可以继续重新映射文件夹,但只能指定其中一个:
android {
sourceSets {
main {
res.srcDirs = ['res']
}
dev {
res.srcDirs = ['res-dev']
}
prod {
res.srcDirs = ['res-prod']
}
etc...
}
}
请注意确定您的“测试”风格。它真的是你的构建不同的味道还是你的测试apk?
编辑:
对于资源合并问题:它不是合并。合并在不同的源集之间。
因此src/main/raw/foo.prop
会覆盖src/debug/raw/foo.prop
。但是,在您的情况下,请考虑在同一源集上设置的2个源文件夹中具有相同的资源。
这是因为您在每个sourceSets上设置了公共res文件夹和特定于flavor的res。
当你让合并做它的事情时,有一个明确的压倒一切的命令。 Flavors覆盖主要源集,构建类型覆盖flavor。
如果您有两个与相同风味相关联的资源文件夹,我们无法知道选择哪一个。
答案 1 :(得分:0)
我刚刚找到了解决此问题的完美解决方案,请在我的答案How to exclude res folder from gradle build flavours?
中查看