Reputation: 7089
I've got a project, structured like this:
project/
|
|---src/
|---flavorA2/
| |
| |---java/
| | |---com.abc.flavorA.mk2
| | |-----classA.java
| | |-----classB.java
| |---res/
| |---AndroidManifest.xml
|
|---main
| |---java/
| | |---com.abc.flavorA
| | |-----classA.java
| | |-----classB.java
| | |-----classC.java
| | |-----classD.java
| |---res/
| | |---drawable/
| | |---layout/
| | |---values/
| |
| |---AndroidManifest.xml
|
|---flavorA
flavorA
will use the source and assets from main
completely while flavorA2
has some small changes in classA
and classB
and the package name is also changed to com.abc.flavorA.mk2
.
I had the build.gradle
file like this:
...
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
productFlavors {
flavorA2 {
packageName "com.abc.flavorA.mk2"
versionCode 2
versionName "1.0.1"
}
flavorA {
packageName "com.abc.flavorA"
}
}
...
I run the code by selecting the build variant to flavorA2
. However the running results shows that the gradle still choose the classes (classA
and classB
) from main
instead of using the changed version inside flavorA2
.
Am I missing something here?
Upvotes: 76
Views: 49275
Reputation: 10529
Posting this answer here hoping someone might have to implement the same; in my case, I had two static constants where I wanted to assign different values based on the build variant. So, I have created an object and declared the constants, then placed the object in both variants by creating different source sets.
Say the variants are 'Variant_A' & 'Variant_B'
Variant_A/java/package_name.util.variantspec
object ConfigConstant {
// Carousels
/**
* Changing PERCENT_SCALE_X_IN or PERCENT_SCALE_Y_IN should also change the animation scale
* percentages accordingly.
*/
const val PERCENT_SCALE_X_IN = 0.10 // 10% percentage
const val PERCENT_SCALE_Y_IN = 0.10 // 10% percentage
}
Variant_B/java/package_name.util.variantspec
object ConfigConstant {
// Carousels
/**
* Changing PERCENT_SCALE_X_IN or PERCENT_SCALE_Y_IN should also change the animation scale
* percentages accordingly.
*/
const val PERCENT_SCALE_X_IN = 0.15 // 15% percentage
const val PERCENT_SCALE_Y_IN = 0.15 // 15% percentage
}
Accessing from some other class
class VerticalCarouselAdapter() {
companion object {
/**
* Changing PERCENT_SCALE_X_IN or PERCENT_SCALE_Y_IN should also change the animation scale
* percentages accordingly.
*/
const val PERCENT_SCALE_X_IN = ConfigConstant.PERCENT_SCALE_X_IN
const val PERCENT_SCALE_Y_IN = ConfigConstant.PERCENT_SCALE_Y_IN
}
}
Upvotes: 1
Reputation: 2369
Since you have the classes under 2 different packages, these are totally different classes. So the classes aren't replacing each other.
With flavors, you can't override class files. So, one way to accomplish what you want is move these classes out of main
, and into flavorA
.
So you would have something like this:
project/
|
|---src/
|---flavorA2/
| |
| |---java/
| | |---com.abc
| | |-----classA.java
| | |-----classB.java
| |---res/
| |---AndroidManifest.xml
|
|---main/
| |---java/
| | |---com.abc.flavorA
| | |-----classC.java
| | |-----classD.java
| |---res/
| | |---drawable/
| | |---layout/
| | |---values/
| |
| |---AndroidManifest.xml
|
|---flavorA/
| |---java/
| | |---com.abc
| | |-----classA.java
| | |-----classB.java
This way, whenever you pick a flavor, only one version of ClassA and ClassB will be visible.
Upvotes: 130
Reputation: 6699
You need to specify sourceSets
in your build file. You need to modify your directory structure to make it so that only the folder names are different, everything under the java directory should be the same, so remove the mk2
from the class name. I'm not sure if the syntax is entirely correct but it should look like this:
android {
sourceSets {
flavorA {
java {
srcDirs = ['src/flavorA/java']
}
}
flavorA2 {
java {
srcDirs = ['src/flavorA2/java']
}
}
}
}
Upvotes: 6
Reputation: 80010
In the main build variant, Class A is com.abc.flavorA.classA
, and in flavorA2
it's com.abc.flavorA.mk2.classA
. These are two different fully-qualified class names and therefore two different classes.
You can't really override entire classes in a flavor. Depending on what you want to do, you might want to look into the BuildConfig
mechanism -- in short, this is a class that's generated by the build system which can have values or statements that vary depending on the build type and flavor. You can have runtime code that looks at constants in that class and varies its behavior.
See Android Studio Update 0.4.0 could not find buildConfig() for more information on the syntax, but in brief, it looks like this:
productFlavors {
flavor {
buildConfigField "boolean", "MY_FLAG", "true"
}
}
Upvotes: 12