Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup flavors for android gradle project? Mysterious duplicate class error

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: 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?

Full sample project, zipped

like image 754
curioushikhov Avatar asked Oct 21 '22 15:10

curioushikhov


1 Answers

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.

like image 63
antonyt Avatar answered Oct 23 '22 06:10

antonyt