Multi-flavoured Kotlin DSL build script for Android App
There is a number of great articles on Kotlin DSL scripts for Android application. My aim is not to go through the details of the pros and cons of Kotlin DSL over Groovy. Unfortunately, I was not able to find any documentation or examples specifically around “How to write a Kotlin DSL for multi-flavoured application”. In this articles, I will explain the step-by-step process to build a multi-flavoured app.
Let us assume we have a multi-flavoured app such as “Free” and “Paid” with various build types for eq. “Debug”, “QA” and “Release”. The build types are targeted to specific environments. You might have something different flavours and build types based on your requirements.
#1. Create a new project using Android Studio for eq. “KotlinDSL”.
#2. Ensure you can able to build your app successfully.
As a result of the above steps, the Studio should have generated the project structure as below in the project view of the solution.

Let’s briefly go through basics of the build/gradle related files of the generated solution based on the Groovy. Later, we will go through the steps of migrating them to Kotlin DSL.
settings.gradle
The main role of settings.gradle is to define all included submodules and to mark the directory root of a tree of modules, so you can only have one settings.gradle
file in a multi-module project.
include ':app'
gradle.properties
This is optional, it’s main purpose is to provide startup options to use for running gradle itself, e.g.
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
build.gradle
There is one such file per module, it contains the build logic for this module and you need to specify the required dependencies of the plugins required and their corresponding repositories as below as in the main module is at KotlinDSL/build.gradle.
ext.kotlin_version = '1.2.61'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0-rc02'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
In the build.gradle
file of the main module , you can use allprojects {}
or subprojects {}
to define settings for all other modules. Similarly, there is one more build.gradle present inside the app module.
Now, it’s time to start preparing the project to migrate to Kotlin DSL.
#3. Rename all the build.gradle files into build.gradle.kts and start refactoring the code. As a result of the refactoring the code, it would look like the following:
Kotlin DSL for the root build.gradle.kts
Kotlin DSL for the app build.gradle.kts
Now, we are done with the Kotlin DSL migration, build your project now to ensure the migration is successful. But we can definitely improve the codebase by refactoring the dependencies along with the version to a common place for easy maintenance for the upgrade in the future. It makes your life much easier when you need to upgrade a library for multiple modules.
#4. Add a new folder to the root directory called “buildSrc” and sub folders. This can follow the similar package structure as the main app such as src->main->java
This folder is special, it is like a separate gradle project in itself. It builds before doing anything else and can provide the function to use in any other gradle file.
In this demo, let us add three files to the java folder as below to hold the configuration, dependencies and versions into separate files.
Add another build.gradle.kts with the plugin information under the root of the buildSrc .
plugins {
`kotlin-dsl`
}
Upon building your app now further we can refactor the dependencies and versions by using the created static classes for the build.gradle.kts we created in step#3. Let us see below how it looks like after modifying the build.gradle.kts upon reuse of the static classes.
It’s time for the next challenge to think about multi-flavoured and various build types as I had mentioned in the very beginning.
To create various product flavours you need to add required resources and assets in the app along with the name of the flavours such as “Free” and “Paid” where you might have a different experience of the app. As this article is all about the build scripts I am not going through the detail customization here. Please refer https://developer.android.com/studio/build/build-variants for more details.
#5 Add the product flavours and build types blocks to the app build.gradle.kts with different applicationId and build types configurations for each builds.
buildTypes {
val booleanType = "Boolean"
getByName("debug") {
buildConfigField(booleanType, Config.BuildFurniture.ENABLE_ROTATION, false.toString())
isDebuggable = true
}
create("qa") {
buildConfigField(booleanType, Config.BuildFurniture.ENABLE_ROTATION, true.toString())
isShrinkResources = true
isMinifyEnabled = true
isUseProguard = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
getByName("release") {
buildConfigField(booleanType, Config.BuildFurniture.ENABLE_ROTATION, true.toString())
isShrinkResources = true
isMinifyEnabled = true
isUseProguard = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
productFlavors {
create("free") {
applicationId = "sk.android.free"
}
create("paid") {
applicationId = "sk.android.paid"
}
}
In the above code, ENABLE_ROTATION is the configuration specific to your own build types. For eq. you might want to enable orientation changes of the app only in the debug build and so on.
You can also configure if you would like to enable pro-guard and resource minification setting in the build types.
For each product type as well as each flavour you may need to create an *.apk file which is mentioned in the application Id as the google play identifier.
As a result of the above step, each build types and flavours would have created it’s gradle tasks to generate the apks.
#6. Now build your project and see all the tasks with the following command in the Android Studio terminal window.
KotlinDSL SK$ ./gradleW tasks
-----------
assemble - Assembles all variants of all applications and secondary packages.
assembleAndroidTest - Assembles all the Test applications.
assembleDebug - Assembles all Debug builds.
assembleFree - Assembles all Free builds.
assemblePaid - Assembles all Paid builds.
assembleQa - Assembles all Qa builds.
assembleRelease - Assembles all Release builds.
You can use the tasks listed above in your terminal to generate the apk as per your requirement. But if you are after “Free with Debug” or “Paid with Release” you can use assembleFreeDebug(in short — aFDebug) or assemblePaidRelease(aPRelease) commands respectively.