Search code examples
javaandroidlayoutresourcesandroid-productflavors

Product flavors and source hierarchies


My app has two flavors, call it flavora and flavorb for simplicity.

    productFlavors {
        flavora {
            resValue "string", 'app_name', "App Name Flavor A"
            applicationIdSuffix ".flavora"
        }
        flavorb {
            resValue "string", 'app_name', "App Name Flavor B"
            applicationIdSuffix ".flavorb"
        }
    }

I want both flavors to use all the same layouts, all the same java code, all the same resources, etc, EXCEPT I want flavora and flavorb to use different implementations for layout file flavor_dependent_layout.xml and Java class FlavorDependentJavaClass.

Is this the correct way to do it:

sourceSets {
    main {
        res.srcDirs = ['src/main/res']
        java.srcDirs = ['src/main/java']
    }
    flavora {
        res.srcDirs = ['src/flavora/res', 'src/main/res']
        java.srcDirs = ['src/flavora/java', 'src/main/java']
    }
    flavorb {
        res.srcDirs = ['src/flavorb/res', 'src/main/res']
        java.srcDirs = ['src/flavorb/java', 'src/main/java']
    }
}

And then I'd just create the necessary folders to place the corresponding files, and it'll all work from there naturally? How does it know that I've included the class for both flavors in case I try to perform a method and it only exists for one flavor, for example?

(Also, do I have to explicitly mention assets folders? Since I have `/src/main/assets' as well)


Solution

  • Is this the correct way to do it:

    No.

    Just create src/flavora/res/, src/flavora/java/, src/flavorb/res/, and src/flavorb/java/, and put stuff in there. They will automatically be added to the appropriate build paths. You do not need to adjust srcDirs.

    How does it know that I've included the class for both flavors in case I try to perform a method and it only exists for one flavor, for example?

    That's a build error. With Java code, if you want to have it in flavors:

    • The same class cannot exist in main
    • Anything referenced from main has to exist in both flavora and flavorb

    So, for example, if you have an AdStrategy class somewhere inside src/flavora/java/ and somewhere inside src/flavorb/java/, you would not also have AdStrategy in src/main/java/. And anything that main refers to on AdStrategy (constructors, methods, etc.) has to exist in both flavora and flavorb's implementation of AdStrategy. At build time, when you are building flavora, the src/main/java/ and src/flavora/java/ trees are used automatically, and whatever you refer to in main needs to resolve (likewise for flavorb builds).