I'm setting up the product flavors in my app and have run into one problem. Two of my product flavors are very similar to each other and only differ by a few resources, let's call them FlavorA and FlavorB. I would like to set it up so that FlavorA is the parent of FlavorB, that way FlavorB can just override a few resources of FlavorA, and then FlavorA overrides a bunch of resources from main. Is there a way to set up a flavor hierarchy such as this? Right now I need to duplicate lots of resources between the two in order for it to work and I would like to eliminate that duplication.
edit: OK. I've had a couple answers so far (both deleted) that were not related to my question so let me clarify. This does not have to do with Java OOP, I already know that quite well. :)
The issue I'm having is that I have a free/paid version of my app, and then several white labels that only include theme changes. The paid version only changes a few assets from the free version (apart from code changes). This is what my productFlavors
look like:
productFlavors {
whiteLabelA {
applicationId "com.whiteLabelA.android"
}
whiteLabelB {
applicationId "com.whiteLabelB.android"
}
mainFree {
applicationId "com.mainFree.android"
}
mainPaid {
applicationId "com.mainFree.android.paid"
}
}
I would like mainPaid
to override mainFree
since it only changes a few resources. I would like to do it this way rather than a free/paid build type because the white labels don't have paid versions, and it would be easier to have a flavor hierarchy like:
mainPaid extends mainFree {
applicationId "com.mainFree.android.paid"
}
I found two solutions:
1. Use flavor dimensions.
android {
...
flavorDimensions 'palette', 'color'
productFlavors {
blackAndWhite {
dimension 'palette'
}
redAndWhite {
dimension 'palette'
}
red {
dimension 'color'
}
white {
dimension 'color'
}
}
variantFilter { variant ->
def first = variant.getFlavors().get(0).name
def second = variant.getFlavors().get(1).name
if(!(first.equals('blackAndWhite') && second.equals('white')) ||
!(first.equals('redAndWhite') && (second.equals('white') || second.equals('red')))) {
variant.setIgnore(true);
}
}
...
}
Because of variantFilter
we have 3 combinations instead of 4:
blackAndWhite => white
redAndWhite => white
=> red
You can consider that as red
extending redAndWhite
and white
extending blackAndWhite
or redAndWhite
.
This answer and variant filter documentation were helpful.
2. Edit source set.
productFlavors{
flavor1 {
}
flavor2 {
}
}
sourceSets {
flavor2 {
java.srcDirs = sourceSets.flavor1.java.srcDirs
res.srcDirs = sourceSets.flavor1.res.srcDirs
resources.srcDirs = sourceSets.flavor1.resources.srcDirs
aidl.srcDirs = sourceSets.flavor1.aidl.srcDirs
renderscript.srcDirs = sourceSets.flavor1.renderscript.srcDirs
assets.srcDirs = sourceSets.flavor1.assets.srcDirs
}
}
Code example was shamelessly copied from this blog post. Big thanks to its author.
I was looking for a similar thing in gradle and found Multi-flavor variants. I have an app that should have versions A and B, and each version has dev and pro environments, so I ended up with this in my gradle:
flavorDimensions 'app', 'environment'
productFlavors {
versionA {
flavorDimension 'app'
}
versionB {
flavorDimension 'app'
}
pre {
flavorDimension 'environment'
}
pro {
flavorDimension 'environment'
}
}
And in my build variants I have versionAPreDebug, versionAPreRelease, versionBPreDebug, versionBPreRelease, etc. I think what you need is something like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With