Blogs Gradle Product Flavors and Build Types
Post
Cancel

Gradle Product Flavors and Build Types

Preview Image

One solution might be to have multiple versions of your app like the Free Version and Paid Version. Luckily for you, Gradle supports this at the building level, allowing you to define the boundaries of different build types. However, before getting started, you need to understand how Gradle allows you to work with different app versions.

Build Types

By default, there are two build types — debug and release. The only difference between them is the value of the debuggable parameter. In other words, you can use the debug version to review logs and to debug the app, while the release one is used to publish your app to the Google Play Store. You can configure properties to the build types by adding the following code in the android block of your module-level build.gradle file:

1
2
3
4
5
6
7
8
buildTypes {
    release {

    }
    debug {

    }
}

In the debug and release blocks you can specify the type-specific settings of your application.

Build Signing

One of the most important configurations of the build is its signature. Without a signature, you will be unable to publish your application, since it’s necessary to verify you as an owner of the specific application. While you don’t need to sign the debug build - Android Studio does it automatically - the release build should be signed by a developer.

When your Keystore is ready, add the code below in the android block and above the buildTypes block (the order of declaration matters) of the module-level build.gradle file:

1
2
3
4
5
6
7
8
signingConfigs {
    release {
        storeFile file("path/to/your/keystore/file")
        storePassword "your-store-password"
        keyAlias "your-key-alias"
        keyPassword "your-key-password"
    }
}

In the signingConfigs block, you specify your signature info for the build types. Update the buildTypes block to sign your release build automatically:

1
2
3
release {
    signingConfig signingConfigs.release
}

Build Flavors

In order to create multiple versions of your app, you need to use product flavors. Flavors are a way to differentiate the properties of an app, whether it’s free/paid, staging/production, etc.

You will distinguish your app flavors with different app names. First, add the following names as strings in the strings.xml file:

1
2
<string name="app_name_free">GradleExample Free</string>
<string name="app_name_paid">GradleExample Paid</string>

And remove the existing:

1
<string name="app_name">GradleExample</string>

Now that the original app_name the string is no longer available, edit your AndroidManifest.xml file and replace android:label="@string/app_name" with android:label="${appName}" inside the application tag.

Add the following code in the android block of your module-level build.gradle file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1
flavorDimensions "appMode"
// 2
productFlavors {
    // 3
    free {
        // 4
        dimension "appMode"
        // 5
        applicationIdSuffix ".free"
        // 6
        manifestPlaceholders = [appName: "@string/app_name_free"]
    }
    paid {
        dimension "appMode"
        applicationIdSuffix ".paid"
        manifestPlaceholders = [appName: "@string/app_name_paid"]
    }
}
  1. You need to specify the flavor dimensions to properly match the build types. In this case, you need only one dimension which is the app mode.
  2. In the productFlavors, specify a list of flavors and their settings. In this case, free and paid.
  3. Specify the name of the first product flavor which is free.
  4. It’s mandatory to specify the dimension parameter value. The free flavor belongs to the appMode dimension.
  5. Since you want to create separate apps for free and paid functionality, you need them to have different app identifiers. The applicationIdSuffixparameter defines a string that will be appended to the applicationId giving your app unique identifier.
  6. The manifestPlaceholders allows you to modify properties in your AndroidManifest.xml file at build time. In this case, modify the application name depending on its version.

Sync your project with Gradle again. After the project sync, run ./gradlew tasks and see if you can spot what’s changed. You’ll get a similar list of tasks to the one you got when you ran this command the first time:

1
2
3
4
5
6
7
8
9
...
Build tasks
-----------
...
assembleDebug - Assembles all Debug builds.
assembleFree - Assembles all Free builds.
assemblePaid - Assembles all Paid builds.
assembleRelease - Assembles all Release builds.
...

Spot the difference? If you pay attention to the tasks under the Build tasks section, you should have some new ones there. You now have separate commands for each building type and build flavor.

So, what you have actually generated are different build variants, which are a combination of build types debug and release . And build flavors free *and paid. That is to say, you have four possible build variants paidDebug, paidRelease, freeDebug, and freeRelease.

This post is licensed under CC BY 4.0 by the author.