对具有完全相同配置的许多源集中的一些进行分组

时间:2016-03-20 09:36:06

标签: android android-studio gradle android-productflavors android-sourcesets

假设我有以下SELECT * FROM YourTable t WHERE NOT EXISTS(SELECT 1 FROM YourTable s WHERE t.post_id = s.post_id AND t.created_time < s.created_time GROUP BY post_id HAVING count(*) > 3)

sourceSets

如果您发现sourceSets { flavor1 { assets.srcDirs = ['repo-assets/flavor1'] res.srcDirs = ['repo-res/flavor1'] } flavor2 { assets.srcDirs = ['repo-assets/flavor2'] res.srcDirs = ['repo-res/flavor2'] } flavor3 { assets.srcDirs = ['repo-assets/flavor1'] res.srcDirs = ['repo-res/flavor1'] } flavor4 { assets.srcDirs = ['repo-assets/flavor2'] res.srcDirs = ['repo-res/flavor2'] } } flavor1具有相同的srcDirs,flavor3flavor2也是如此。

尝试可能性#1

我试图通过使用类似的东西来确定是否有办法避免冗余:

flavor4

以上不起作用(已经尝试过)。寻找类似的东西,这样我就可以为一组风味提供一套通用的sourceSets { flavor1, flavor3 { assets.srcDirs = ['repo-assets/flavor1'] res.srcDirs = ['repo-res/flavor1'] } flavor2, flavor4 { assets.srcDirs = ['repo-assets/flavor2'] res.srcDirs = ['repo-res/flavor2'] } } 。有人试过做类似的事情,可以提供一些指示吗?

尝试可能性#2

sourceDirs的名称是否需要与口味相同?

我可以单独命名sourceSets,然后将它们映射到sourceSets吗?

productFlavors

尝试可能性#3

可以通过某种方式动态分配源集来实现相同的东西吗?

更新

Douglas的回答有点帮助我最终得到了我正在寻找的东西(减少了build.gradle中的代码)。他使用了上面的可能性#3。谢谢道格拉斯!任何更好的替代赏金猎人仍然是受欢迎的(更接近上面的可能性#1和#2)。如果没有出现任何问题,那么当道格拉斯已经结束时,我已经接受了他的答案。但仍然会对寻找更好的替代方案保持乐观。

3 个答案:

答案 0 :(得分:4)

你的第一种可能性也非常接近:

sourceSets {
    [flavor1, flavor3].each {
        it.assets.srcDirs = ['repo-assets/flavor1']
        it.res.srcDirs = ['repo-res/flavor1']
    }
    [flavor2, flavor4].each {
        it.assets.srcDirs = ['repo-assets/flavor2']
        it.res.srcDirs = ['repo-res/flavor2']
    }
}

以上在IDEA编辑器中看起来不太好,会显示很多警告。如果要获得代码完成,可以设置类型:

import com.android.build.gradle.api.AndroidSourceSet
android {
    sourceSets {
        [flavor2, flavor4].each { AndroidSourceSet ss ->
            ss.assets.srcDirs = ['repo-assets/flavor2']
            ss.res.srcDirs = ['repo-res/flavor2']
        }
    }
}

另一个技巧:这种风格的定义与源集列表位于同一位置。

android
    productFlavors {
        flavor1 {
            applicationId "flavor1.app.id"
        }
        flavor2 {
            applicationId "flavor2.app.id"
        }
        [flavor1, flavor2].each {
            sourceSets[it.name].assets.srcDirs = ['repo-assets/flavor1']
            sourceSets[it.name].res.srcDirs = ['repo-assets/flavor1']
        }
    }

无论你去哪里,关于srcDirssee source也是值得注意的事情:

println assets.srcDirs // say it's [src/flavor/assets]
assets.srcDirs = ['dir1', 'dir2'] // overwrites existing directories: output would be [dir1, dir2]
assets.srcDirs 'dir1', 'dir2' // appends existing directories: output would be [src/flavor/assets, dir1, dir2]
assets.srcDir 'dir1' // appends only one dir, output would be [src/flavor/assets, dir1]

答案 1 :(得分:1)

您可以定义一个复制风格的函数(android {}之外):

def copyFlavor(flavordest, flavororig) {
    flavordest.resources.srcDirs = flavororig.resources.srcDirs
    flavordest.res.srcDirs = flavororig.res.srcDirs
    flavordest.aidl.srcDirs = flavororig.aidl.srcDirs
    flavordest.java.srcDirs = flavororig.java.srcDirs
    flavordest.assets.srcDirs = flavororig.assets.srcDirs
    flavordest.renderscript.srcDirs = flavororig.renderscript.srcDirs

    // if you don't need all of this, remove them. There are much more too, like `jni` and `jniLibs`
}

然后在源集上调用此函数:

sourceSets {
    copyFlavor(flavor3, flavor1)  // flavor3 = flavor1
    copyFlavor(flavor4, flavor2)  // flavor4 = flavor2
}

当然,只有你有多种口味才有价值,只有两种,写一个功能的开销更大。

编辑 添加我使用的项目结构

为简化而不需要指定flavor1和flavor2路径,我使用了标准结构来进行调味:

app/
    src/
        androidTest/
        flavor1/
            assets/
            res/
                values/strings.xml
        flavor2/
            assets/
            res/
                values/strings.xml
        main/
            assets/
            java/
            res/
                values/strings.xml
        test/

values.xml的字符app_name包含[{1}}的内容"SourceSets"main的{​​{1}}和"SourceSets 1"的{​​{1}} 1}}。

只需以标准方式定义flavor1和flavor2路径,然后使用提供的功能将其复制。

编辑2: 我尝过的东西,可能有些东西会起作用,但没有一个在这里(可能是我犯了一些愚蠢的错误)

我尝试过但没有用的东西:

A:
1. flavor1
2. "SourceSets 2"
3. flavor2
4. flavor3.root = "flavor1"
这些已编译,但我定义为测试的字符串资源没有改变。

B:
flavor3.root = "flavor1/"
这甚至不编译,flavor3.setRoot("flavor1")是只写的。

C:
flavor3.setRoot("flavor1/")
这也编译了,但没有效果。请注意,它与 A 不同,因为在 A 中,右侧是字符串。

d:
我也有flavor3.root = flavor1.root的想法,但是当我尝试它时,我可能犯了一些愚蠢的错误而且它也没有用:

.root

最后一个我有一些希望,但无法管理。然后我坚持flavor3.root = flavor1功能。以上所有我也试过预先[].each(例如, [flavor2, flavor4].each { it.res.srcDirs = ["flavor2/res"] it.resources.srcDirs = ["flavor2/res"] it.assets.srcDirs = ["flavor2/assets"] } ),但不成功。

答案 2 :(得分:1)

我认为@jmols试图在评论中说的是这样的:

从结构出发

repo-assets
    flavor1
    flavor2
repo-res
    flavor1
    flavor2

flavor1
    assets
    res
flavor2
    assets
    res

并使用

sourceSets {
    //flavor1.setRoot('flavor1') // default
    //flavor2.setRoot('flavor2') // default
    flavor3.setRoot('flavor1')
    flavor4.setRoot('flavor2')
}

请参阅http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Project-Structure了解setRoot和默认结构。 这是source code of setRoot,注意它会重置所有自定义项,这就是为什么匹配默认结构至关重要的原因。其内置呼叫位于here