每种构建风格使用几个不同资源文件的更好方法

时间:2014-01-06 22:36:14

标签: android gradle

我正在尝试构建一个具有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如何合并这些类型的文件?

2 个答案:

答案 0 :(得分:22)

这太过分了。

你需要的只是:

src/main/res

这是您所有口味的共同资源

src/dev/res

这是dev风格特有的资源。

src/prod/res

这是prod风格特有的资源。

等...

注意:如果您在src/main/ressrc/<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?

中查看