My app has several flavors for several markets in-app-billing systems.
I have a single library which shares the base code for all of my projects. So I decided to add those payment systems to this library as product flavors.
The question is can android library have product flavors?
If so, how can I include different flavors in respective flavor of the app?
I searched a lot, and I couldn't find anything about this scenario. The only close thing I found was this in http://tools.android.com/tech-docs/new-build-system/user-guide:
dependencies {
flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}
I changed configuration to different things but it did not work!
I'm using android studio 0.8.2.
Finally I found out how to do this, I will explain it here for others facing same problem:
It's possible since Gradle Plugin 3.0.0 (and later) to do something like:
Library build.gradle:
apply plugin: 'com.android.library'
// Change below's relative-path
// (as the `../` part is based on my project structure,
// and may not work for your project).
apply from: '../my-flavors.gradle'
dependencies {
// ...
}
android {
// ...
}
Project build.gradle:
buildscript {
// ...
}
apply plugin: 'com.android.application'
// Note that below can be put after `dependencies`
// (I just like to have all apply beside each other).
apply from: './my-flavors.gradle'
dependencies {
api project(':lib')
}
android {
productFlavors {
// Optionally, configure each flavor.
market1 {
applicationIdSuffix '.my-market1-id'
}
market2 {
applicationIdSuffix '.my-market2-id'
}
}
}
My flavors .gradle:
android {
flavorDimensions 'my-dimension'
productFlavors {
market1 {
dimension 'my-dimension'
}
market2 {
dimension 'my-dimension'
}
}
}
The key part is to set publishNonDefault
to true
in library build.gradle
, Then you must define dependencies as suggested by user guide.
Update 2022;
publishNonDefault
is now by defaulttrue
, and setting it tofalse
is ignored, since said option is deprecated.
The whole project would be like this:
Library build.gradle:
apply plugin: 'com.android.library'
android {
....
publishNonDefault true
productFlavors {
market1 {}
market2 {}
market3 {}
}
}
project build.gradle:
apply plugin: 'com.android.application'
android {
....
productFlavors {
market1 {}
market2 {}
market3 {}
}
}
dependencies {
....
market1Compile project(path: ':lib', configuration: 'market1Release')
market2Compile project(path: ':lib', configuration: 'market2Release')
// Or with debug-build type support.
android.buildTypes.each { type ->
market3Compile project(path: ':lib', configuration: "market3${type.name}")
}
}
Now you can select the app flavor and Build Variants panel and the library will be selected accordingly and all build and run will be done based on the selected flavor.
If you have multiple app module based on the library Android Studio will complain about Variant selection conflict, It's ok, just ignore it.
There are one problem with Ali answer. We are losing one very important dimension in our build variants. If we want to have all options (in my example below 4 (2 x 2)) we just have to add custom configurations in main module build.gradle file to be able to use all multi-flavor multi-buildType in Build Variants
. We also have to set publishNonDefault true in the library module build.gradle file.
Example solution:
Lib build.gradle
android {
publishNonDefault true
buildTypes {
release {
}
debug {
}
}
productFlavors {
free {
}
paid {
}
}
}
App build.gradle
android {
buildTypes {
debug {
}
release {
}
}
productFlavors {
free {
}
paid {
}
}
}
configurations {
freeDebugCompile
paidDebugCompile
freeReleaseCompile
paidReleaseCompile
}
dependencies {
freeDebugCompile project(path: ':lib', configuration: 'freeDebug')
paidDebugCompile project(path: ':lib', configuration: 'paidDebug')
freeReleaseCompile project(path: ':lib', configuration: 'freeRelease')
paidReleaseCompile project(path: ':lib', configuration: 'paidRelease')
}
Update for Android Plugin 3.0.0 and higher
According to the official Android Documentation - Migrate dependency configurations for local modules,
With variant-aware dependency resolution, you no longer need to use variant-specific configurations, such as freeDebugImplementation, for local module dependencies—the plugin takes care of this for you
You should instead configure your dependencies as follows:
dependencies {
// This is the old method and no longer works for local
// library modules:
// debugImplementation project(path: ':library', configuration: 'debug')
// releaseImplementation project(path: ':library', configuration: 'release')
// Instead, simply use the following to take advantage of
// variant-aware dependency resolution. You can learn more about
// the 'implementation' configuration in the section about
// new dependency configurations.
implementation project(':library')
// You can, however, keep using variant-specific configurations when
// targeting external dependencies. The following line adds 'app-magic'
// as a dependency to only the "debug" version of your module.
debugImplementation 'com.example.android:app-magic:12.3'
}
So in Ali's answer, change
dependencies {
....
market1Compile project(path: ':lib', configuration: 'market1Release')
market2Compile project(path: ':lib', configuration: 'market2Release')
}
to
implementation project(':lib')
And plugin will take care of variant specific configurations automatically. Hope it helps to others upgrading Android Studio Plugin to 3.0.0 and higher.
My Android Plugin is 3.4.0,and I find that it doesn't need configurations now.All you need is to make sure the flavorDimensions and productFlavors in application contains one productFlavor of the same flavorDimensions and productFlavors in libraries.For sample:
In mylibrary's build.gradle
apply plugin: 'com.android.library'
android {
....
flavorDimensions "mylibFlavor"
productFlavors {
market1
market2
}
}
application's build.gradle:
apply plugin: 'com.android.application'
android {
....
flavorDimensions "mylibFlavor", "appFlavor"
productFlavors {
market1 {
dimension "mylibFlavor"
}
market2 {
dimension "mylibFlavor"
}
common1 {
dimension "appFlavor"
}
common2 {
dimension "appFlavor"
}
}
}
dependencies {
....
implementation project(path: ':mylibrary')
}
After sync,you can switch all options in Build Variants Window:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With