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
To use flavors to vary source sets,
productFlavors{
phone{
}
tablet{
}
}
Now structure your code like,
src
main
phone
tablet
The code in main
is common between both flavors, but the code in phone
or tablet
is only included when the respective flavor is built. That's it, you don't need to do anything else.
The structure under phone
and tablet
is the same as under main
(res
, java
, etc). You can also have a custom AndroidManifest.xml
under the flavor directory. Gradle attempts to merge the flavor's AndroidManifest.xml
with the one in main. In some cases you have to provide rules for how to merge.
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 has an expected structure for a sourceset:
res/
java/
jniLibs/
assets/
Where the sourceSets
closure comes into play is if, for a given sourceset, you want a different structure:
foo/
bar/
ickyNativeStuff/
assetsBecauseThatSeemsLikeADecentName/
Each build type, product flavor, and build variant can have a separate sourceset (as can androidTest
for instrumentation testing), to go along with main
. They are named the same as the build type/product flavor/build variant. These will be in the stock structure, unless you use sourceSets
to change things.
So, to roll all the way back to:
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
In the case of resources, other sourcesets overlay main
. So, if you have src/main/res/...
and src/main/debug/...
and src/main/release/...
, and you are doing a debug
build, whatever is in src/main/release/...
is ignored (as we aren't doing release
) and whatever is in src/main/res/...
and src/main/debug/...
will be used. If there is the same resource in both (src/main/res/raw/boom.ogg
and src/debug/res/raw/boom.ogg
), the debug
one trumps the main
one.
I have not experimented with varying jniLibs/
by build variant. My guess is that it will behave more like Java code, where you cannot have conflicts between what is in a build variant's sourceset and what is in main
, but that's just a guess. So, you can have the debug version of your compiled JNI code in src/debug/jniLibs/
and the release version of your compiled JNI code in src/release/jniLibs/
. Only have in src/main/jniLibs/
any libraries that are not varying. That being said, as I mentioned, I haven't tried this, and so there may be hiccups here.
So, I would expect you to not have a sourcesets
closure in build.gradle
, and to just use the stock sourcesets structure, for your various bits:
src/
main/
...
debug/
jniLibs/
res/
raw/
release
jniLibs/
res/
raw/
Anything that's normally under src/main/
can be put in a different folder:
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
Where element
is the name of a build type
or a product flavor
. If your variant includes such a element (build type or flavor), then that source set is also used in addition to src/main
Note that the location is really not relevant if you have configured it.
What matters is that there is a android.sourcesets.main
element that contains the sources common to all variants, and each variant has a set of sourcesets.
For instance if you have a flavor phoneRelease
it's really using the following sourcesets:
android.sourcesets.main
android.sourcesets.phone
android.sourcesets.release
android.sourcesets.phoneRelease
If you have another variant tabletRelease
, it'll use the following:
android.sourcesets.main
android.sourcesets.tablet
android.sourcesets.release
android.sourcesets.phoneRelease
So the phone
/tablet
sourceset is different and is where you'd put the variant specific sources, unless you want to be even more specific and use the phoneRelease
/tabletRelease
sourcesets (though those are less used generally.) By default these would be src/phone/...
and src/tablet/...
(or src/phoneRelease/...
) but you can change that however you want and as long as it's connected to the android.sourcesets.*
objects it'll be fine.
for example, doing:
android {
sourcesets {
phone {
jniLibs.srcDirs = ['phoneRelease/jniLibs/']
}
tablet {
jniLibs.srcDirs = ['tabletRelease/jniLibs/']
}
}
}
is fine. But do be aware that you only changed the jniLibs folder and not the other source elements (java, res, etc...)
If you kept the default location for the main
sourcesets, I'd just keep everything under src/
You can see more info about sourcesets and how multiple sourcesets are combined here: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Sourcesets-and-Dependencies