Reputation: 2838
I have created simple test project: the goal is to show the message 'hello' by pressing a button on the screen. The first flavor build should write the message to the system log. The second flavor build should show a toast with message. How can this be achieved using gradle please?
My build.gradle:
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
productFlavors {
toast {
}
log {
}
}
sourceSets {
main {
java.srcDirs = ['src/main/java', 'src/log/java']
}
toast {
java.srcDirs = ['src/main/java', 'src/toast/java']
}
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
File structure:
Flavor log
contains single class Messenger with method showMessage(Context context, CharSequence text)
and prints text using Log.i(tag, msg)
Flavor toast
contains single class Messenger with method showMessage(Context context, CharSequence text)
and shows toast with some text.
Main sources don't contain this class.
Why does the error duplicate class:com.test.flavortest.Messenger
appear? Each flavor has a set of different non-crossing source paths?
Upvotes: 5
Views: 3476
Reputation: 1
All source code in the java/ directories are compiled together to generate a single output.
Note: For a given build variant, Gradle throws a build error if it encounters two or more source set directories that have defined the same Java class. For example, when building a debug APK, you cannot define both src/debug/Utility.java and src/main/Utility.java. This is because Gradle looks at both these directories during the build process and throws a 'duplicate class' error. If you want different versions of Utility.java for different build types, you can have each build type define its own version of the file and not include it in the main/ source set.
Upvotes: 0
Reputation: 21883
In your sourcesets definition, you seem to be adding the log
sources to main
:
sourceSets {
main {
java.srcDirs = ['src/main/java', 'src/log/java']
}
toast {
java.srcDirs = ['src/main/java', 'src/toast/java']
}
}
main
is the default sourceset included in all flavors. This would cause a duplicate class (Messenger
) being loaded when building the toast
flavor.
Try specifying the log
and toast
sourcesets only:
sourceSets {
log {
java.srcDirs = ['src/main/java', 'src/log/java']
}
toast {
java.srcDirs = ['src/main/java', 'src/toast/java']
}
}
Your file structure seems to match the default, so an even better solution would be to remove the sourcesets block entirely. src/main/java
is included by default, and then src/flavor/java
is added afterwards automatically.
Upvotes: 3
Reputation: 545
Use assembleToast / assembleLog to Build an specific Flavour. Same for installToast e.g
The global assemble will use every File in the directory.
Upvotes: 0