Gradle 根据构建风格交换 jniLibs 资源
Gradle swap jniLibs resources based on build flavor
我正在尝试根据 release buildType
或 debug buildType
文件夹交换 res/raw
文件夹和 jniLibs/armeabi
文件夹中的一些资源。我目前也有两种产品口味。
build.gradle 文件:
apply plugin: 'com.android.application'
android {
dexOptions {
preDexLibraries = false
}
compileSdkVersion 21
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.test"
minSdkVersion 17
targetSdkVersion 22
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
productFlavors{
phone{
applicationId "com.example.testPhone"
}
tablet{
applicationId "com.example.testTablet"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets{
release{
res.srcDirs = ['androidRelease/res/raw']
}
}
}
dependencies {
compile project(':facebook')
}
使用 sourceSet
的方法是否正确?如果是,应该创建什么文件夹,以便它仅根据 buildType
交换适当的资源,而不考虑 productFlavors
?
编辑:是否可以交换 jniLibs
和 raw
文件夹资源?
文件夹结构:
src/main/jniLibs/armeabi
phoneRelease/jniLibs/armeabi
tabletRelease/jniLibs/armeabi
文件夹结构是否正确?
编辑 2:
根据 Xavier 的回答,gradle 应该是这样的:
android {
sourcesets {
phone {
jniLibs.srcDirs = ['phoneRelease/jniLibs/']
res.srcDirs = ['androidRelease/res/raw']
}
tablet {
jniLibs.srcDirs = ['tabletRelease/jniLibs/']
res.srcDirs = ['androidRelease/res/raw']
}
}
}
我一直在阅读很多相互矛盾的答案,其中一些提到您只需要基于构建变体的单独文件夹,还有一些提到必须使用 sourceSet
?
谢谢!
要使用风格来改变源集,
productFlavors{
phone{
}
tablet{
}
}
现在构建你的代码,
src
main
phone
tablet
main
中的代码在两种风格之间是通用的,但 phone
或 tablet
中的代码仅在构建各自的风格时包含。就是这样,你不需要做任何其他事情。
phone
和 tablet
下的结构与 main
下的相同(res
、java
等)。也可以在flavor目录下自定义AndroidManifest.xml
。 Gradle 尝试将 flavor 的 AndroidManifest.xml
与 main 中的合并。在某些情况下,您必须提供有关如何合并的规则。
通常在 src/main/
下的任何内容都可以放在不同的文件夹中:
src/<element>/AndroidManifest.xml
src/<element>/java
src/<element>/res
src/<element>/assets
src/<element>/resources
src/<element>/jni
src/<element>/jniLibs
src/<element>/aidl
src/<element>/rs
其中 element
是 build type
或 product flavor
的名称。如果您的变体包含这样的元素(构建类型或风格),那么除了 到 src/main
之外,还会使用该源集
请注意,如果您配置了位置,则该位置确实无关紧要。
重要的是有一个 android.sourcesets.main
元素包含所有变体共有的源,每个变体都有一组源集。
例如,如果您有一种风格 phoneRelease
,它实际上使用了以下资源集:
android.sourcesets.main
android.sourcesets.phone
android.sourcesets.release
android.sourcesets.phoneRelease
如果您有另一个变体 tabletRelease
,它将使用以下内容:
android.sourcesets.main
android.sourcesets.tablet
android.sourcesets.release
android.sourcesets.phoneRelease
所以 phone
/tablet
源集是不同的,它是你放置变体特定源的地方,除非你想更具体并使用 phoneRelease
/ tabletRelease
sourcesets(尽管这些通常较少使用。)默认情况下,这些将是 src/phone/...
和 src/tablet/...
(或 src/phoneRelease/...
),但您可以根据需要更改它,只要因为它连接到 android.sourcesets.*
个对象,所以没问题。
例如,做:
android {
sourcesets {
phone {
jniLibs.srcDirs = ['phoneRelease/jniLibs/']
}
tablet {
jniLibs.srcDirs = ['tabletRelease/jniLibs/']
}
}
}
很好。但请注意,您只更改了 jniLibs 文件夹,而没有更改其他源元素(java、res 等...)
如果您保留 main
源集的默认位置,我会将所有内容保留在 src/
下
您可以在此处查看有关源集以及多个源集如何组合的更多信息:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Sourcesets-and-Dependencies
some of them mention that you just need separate folders based on build variant and some mention about having to use sourceSet?
Gradle/Gradle for Android 具有预期的源集结构:
- Android 资源在
res/
- Java
java/
中的源代码树
jniLibs/
中的预编译 JNI 库
- 资产在
assets/
- 等等
sourceSets
闭包发挥作用的地方是,对于给定的源集,您想要一个不同的结构:
- Android 资源位于
foo/
- Java
bar/
中的源代码树
ickyNativeStuff/
中的预编译 JNI 库
- 资产在
assetsBecauseThatSeemsLikeADecentName/
- 等等
每个构建类型、产品风格和构建变体都可以有一个单独的源集(androidTest
可以用于仪器测试),与 main
一起使用。它们的名称与构建 type/product flavor/build 变体相同。这些将在库存结构中,除非您使用 sourceSets
进行更改。
所以,一路滚回:
I am trying to swap some resources in the res/raw folder and the jniLibs/armeabi folder based on whether its a release buildType or a debug buildType
在资源的情况下,其他源集覆盖 main
。因此,如果您有 src/main/res/...
和 src/main/debug/...
以及 src/main/release/...
,并且您正在进行 debug
构建,则 src/main/release/...
中的任何内容都将被忽略(因为我们没有t 做 release
) 并且 src/main/res/...
和 src/main/debug/...
中的任何内容都将被使用。如果两者(src/main/res/raw/boom.ogg
和 src/debug/res/raw/boom.ogg
)中有相同的资源,则 debug
胜过 main
。
我还没有尝试通过构建变体来改变 jniLibs/
。我的猜测是它的行为更像 Java 代码,其中构建变体的源集中的内容与 main
中的内容不会有冲突,但这只是一个猜测。因此,您可以在 src/debug/jniLibs/
中获得已编译 JNI 代码的调试版本,在 src/release/jniLibs/
中获得已编译 JNI 代码的发布版本。只有 src/main/jniLibs/
中没有变化的库。话虽这么说,正如我提到的,我还没有尝试过这个,所以这里可能会有问题。
所以,我希望您在 build.gradle
中没有 sourcesets
闭包,并且只使用 stock sourcesets 结构,用于您的各种位:
src/
main/
...
debug/
jniLibs/
res/
raw/
release
jniLibs/
res/
raw/
我正在尝试根据 release buildType
或 debug buildType
文件夹交换 res/raw
文件夹和 jniLibs/armeabi
文件夹中的一些资源。我目前也有两种产品口味。
build.gradle 文件:
apply plugin: 'com.android.application'
android {
dexOptions {
preDexLibraries = false
}
compileSdkVersion 21
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.test"
minSdkVersion 17
targetSdkVersion 22
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
productFlavors{
phone{
applicationId "com.example.testPhone"
}
tablet{
applicationId "com.example.testTablet"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets{
release{
res.srcDirs = ['androidRelease/res/raw']
}
}
}
dependencies {
compile project(':facebook')
}
使用 sourceSet
的方法是否正确?如果是,应该创建什么文件夹,以便它仅根据 buildType
交换适当的资源,而不考虑 productFlavors
?
编辑:是否可以交换 jniLibs
和 raw
文件夹资源?
文件夹结构:
src/main/jniLibs/armeabi
phoneRelease/jniLibs/armeabi
tabletRelease/jniLibs/armeabi
文件夹结构是否正确?
编辑 2: 根据 Xavier 的回答,gradle 应该是这样的:
android {
sourcesets {
phone {
jniLibs.srcDirs = ['phoneRelease/jniLibs/']
res.srcDirs = ['androidRelease/res/raw']
}
tablet {
jniLibs.srcDirs = ['tabletRelease/jniLibs/']
res.srcDirs = ['androidRelease/res/raw']
}
}
}
我一直在阅读很多相互矛盾的答案,其中一些提到您只需要基于构建变体的单独文件夹,还有一些提到必须使用 sourceSet
?
谢谢!
要使用风格来改变源集,
productFlavors{
phone{
}
tablet{
}
}
现在构建你的代码,
src
main
phone
tablet
main
中的代码在两种风格之间是通用的,但 phone
或 tablet
中的代码仅在构建各自的风格时包含。就是这样,你不需要做任何其他事情。
phone
和 tablet
下的结构与 main
下的相同(res
、java
等)。也可以在flavor目录下自定义AndroidManifest.xml
。 Gradle 尝试将 flavor 的 AndroidManifest.xml
与 main 中的合并。在某些情况下,您必须提供有关如何合并的规则。
通常在 src/main/
下的任何内容都可以放在不同的文件夹中:
src/<element>/AndroidManifest.xml
src/<element>/java
src/<element>/res
src/<element>/assets
src/<element>/resources
src/<element>/jni
src/<element>/jniLibs
src/<element>/aidl
src/<element>/rs
其中 element
是 build type
或 product flavor
的名称。如果您的变体包含这样的元素(构建类型或风格),那么除了 到 src/main
请注意,如果您配置了位置,则该位置确实无关紧要。
重要的是有一个 android.sourcesets.main
元素包含所有变体共有的源,每个变体都有一组源集。
例如,如果您有一种风格 phoneRelease
,它实际上使用了以下资源集:
android.sourcesets.main
android.sourcesets.phone
android.sourcesets.release
android.sourcesets.phoneRelease
如果您有另一个变体 tabletRelease
,它将使用以下内容:
android.sourcesets.main
android.sourcesets.tablet
android.sourcesets.release
android.sourcesets.phoneRelease
所以 phone
/tablet
源集是不同的,它是你放置变体特定源的地方,除非你想更具体并使用 phoneRelease
/ tabletRelease
sourcesets(尽管这些通常较少使用。)默认情况下,这些将是 src/phone/...
和 src/tablet/...
(或 src/phoneRelease/...
),但您可以根据需要更改它,只要因为它连接到 android.sourcesets.*
个对象,所以没问题。
例如,做:
android {
sourcesets {
phone {
jniLibs.srcDirs = ['phoneRelease/jniLibs/']
}
tablet {
jniLibs.srcDirs = ['tabletRelease/jniLibs/']
}
}
}
很好。但请注意,您只更改了 jniLibs 文件夹,而没有更改其他源元素(java、res 等...)
如果您保留 main
源集的默认位置,我会将所有内容保留在 src/
您可以在此处查看有关源集以及多个源集如何组合的更多信息:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Sourcesets-and-Dependencies
some of them mention that you just need separate folders based on build variant and some mention about having to use sourceSet?
Gradle/Gradle for Android 具有预期的源集结构:
- Android 资源在
res/
- Java
java/
中的源代码树
jniLibs/
中的预编译 JNI 库
- 资产在
assets/
- 等等
sourceSets
闭包发挥作用的地方是,对于给定的源集,您想要一个不同的结构:
- Android 资源位于
foo/
- Java
bar/
中的源代码树
ickyNativeStuff/
中的预编译 JNI 库
- 资产在
assetsBecauseThatSeemsLikeADecentName/
- 等等
每个构建类型、产品风格和构建变体都可以有一个单独的源集(androidTest
可以用于仪器测试),与 main
一起使用。它们的名称与构建 type/product flavor/build 变体相同。这些将在库存结构中,除非您使用 sourceSets
进行更改。
所以,一路滚回:
I am trying to swap some resources in the res/raw folder and the jniLibs/armeabi folder based on whether its a release buildType or a debug buildType
在资源的情况下,其他源集覆盖 main
。因此,如果您有 src/main/res/...
和 src/main/debug/...
以及 src/main/release/...
,并且您正在进行 debug
构建,则 src/main/release/...
中的任何内容都将被忽略(因为我们没有t 做 release
) 并且 src/main/res/...
和 src/main/debug/...
中的任何内容都将被使用。如果两者(src/main/res/raw/boom.ogg
和 src/debug/res/raw/boom.ogg
)中有相同的资源,则 debug
胜过 main
。
我还没有尝试通过构建变体来改变 jniLibs/
。我的猜测是它的行为更像 Java 代码,其中构建变体的源集中的内容与 main
中的内容不会有冲突,但这只是一个猜测。因此,您可以在 src/debug/jniLibs/
中获得已编译 JNI 代码的调试版本,在 src/release/jniLibs/
中获得已编译 JNI 代码的发布版本。只有 src/main/jniLibs/
中没有变化的库。话虽这么说,正如我提到的,我还没有尝试过这个,所以这里可能会有问题。
所以,我希望您在 build.gradle
中没有 sourcesets
闭包,并且只使用 stock sourcesets 结构,用于您的各种位:
src/
main/
...
debug/
jniLibs/
res/
raw/
release
jniLibs/
res/
raw/