2

Suppose I have an app that shows locations on a map. Now I want to make several different variations of this app, one showing shops, one showing restaurants, etc.

In some of these apps I want to include ads, in others I don't.

How can I selectively add certain srcDirs to one flavor but not another? I tried the following:

productFlavors {
    Shops {
        applicationId "com.me.shops"
        ext.hasAds = true
    }

    Restaurants {
        applicationId "com.me.restaurants"
        ext.hasAds = false
    }

    ... more flavors with ext.hasAds either true or false
}

applicationVariants.all { variant ->
    String withAdsDir = 'src/withAds'
    String withoutAdsDir = 'src/withoutAds'

    if (variant.productFlavors.get(0).ext.hasAds) {
        variant.sourceSets java.srcDir withAdsDir + '/java'
        variant.sourceSets res.srcDir withAdsDir + '/res'
    }
    else {
        variant.sourceSets java.srcDir withoutAdsDir + '/java'
        variant.sourceSets res.srcDir withoutAdsDir + '/res'
    }
}

But this fails because for one, the syntax in the if-structure is incorrect.

I am trying to avoid having to specify the folders for every flavor individually, therefore using the .ext.hasAds boolean.

How can I achieve specifying particular srcDirs depending on a certain boolean?

UPDATE

I 'fixed' it. Meaning I get what I want. But I'm not very happy about how:

flavorDimensions "adsornot", "typeofapp"

productFlavors {
    Shops {
        applicationId "com.me.shops"
        ext.hasAds = true
        dimension "typeofapp"
    }

    Restaurants {
        applicationId "com.me.restaurants"
        ext.hasAds = false
        dimension "typeofapp"
    }

    Ads {
        ext.hasAds = true
        dimension "adsornot"
    }

    NoAds {
        ext.hasAds = false
        dimension "adsornot"
    }
}

sourceSets {
    String withAdsDir = 'src/withAds'
    String withoutAdsDir = 'src/withoutAds'

    Ads {
        java.srcDir withAdsDir + '/java'
        res.srcDir withAdsDir + '/res'
    }

    NoAds {
        java.srcDir withoutAdsDir + '/java'
        res.srcDir withoutAdsDir + '/res'
    }
}

variantFilter { variant ->
    boolean shouldHaveAds = variant.getFlavors().get(0).ext.hasAds
    boolean variantHasAds = variant.getFlavors().get(1).ext.hasAds

    variant.setIgnore(shouldHaveAds != variantHasAds)
}

Explanation:

I create 2 flavor dimensions: type-of-app, and ads-or-not

This means there will be 4 variants generated. But I only want 2. The variantfilter checks each variant's 2 flavors, they should have matching ext.hasAds (defined in the flavors). If they do not match, ignore this variant.

xorgate
  • 2,244
  • 1
  • 24
  • 36

1 Answers1

0

If you use Android Studio, your app folder contains main folder with default sources, xmls, assets etc. for all configurations. You can also create app/[flavor] folder (for example, app/Shops, app/Restaurants) and put in all specified for the flavor resources.

For example, your build.gradle file contains following flavors:

    flavorDimensions "deployment"

productFlavors {
    development {
        dimension "deployment"
        applicationId "com.example.myapp.dev"
        buildConfigField "boolean", "USE_ADS", "false"
    }
    production {
        dimension "deployment"
        applicationId "com.example.myapp"
        buildConfigField "boolean", "USE_ADS", "true"
    }
}

To create custom resources for development configuration, you need simply create app/development folder. It should have the same structure as the app/main.

After that check custom flags provided in gradle file in your code:

        // check gradle flags
    if (BuildConfig.USE_ADS) {
        // insert ads
    }
  • But I'm specifically not talking about flavors, when talking about using ads or not. Using ads is a property of a flavor, not a flavor itself. – xorgate Apr 26 '16 at 08:11
  • @xorgate: you can provide flag in your build.gradle for ads customized for every flavor. For example, `buildConfigField "boolean", "USE_ADS", "true"` – Victor Semenovich Apr 26 '16 at 08:17
  • But this is not what I want. When using a buildConfigField, the code and resources are added to the apk (and I have to add the library), even when I don't want to use the ads at all. – xorgate Apr 26 '16 at 08:20
  • Well, create separate branches in your repository, that use or don't use ads. You can't add a custom set of libraries only for specified flavor. – Victor Semenovich Apr 26 '16 at 08:23
  • @xorgate: check also this question: http://stackoverflow.com/questions/24860659/multi-flavor-app-based-on-multi-flavor-library-in-android-gradle – Victor Semenovich Apr 26 '16 at 08:27