Using Kotlin for Gradle
Learn how to convert your Gradle scripts from Groovy to Kotlin
This guide will show you a step by step process to convert a brand new Android Studio project build scripts to Kotlin.
Advantages
The default language for Gradle’ scripts is Groovy, it’s a highly dynamic and permissive language which allows you to write the same thing in various ways. You can write something eye pleasing and configuration-like but the drawback is that it’s hard to inspect for the IDE.
For example foo 42
could be a function call (foo(42)
) or a variable assignment (foo = 42
) and 42 could be treated as a number or a string.
Because Gradle makes extensive use of plugins you often have to refer to the plugin’s documentation to see what’s possible.
Switching to Kotlin will give you better code inspection and completion making it that much more simple to maintain your build scripts with your project.
Sadly, the current Android Studio (Flamingo 2022.2) only provides project templates with Groovy files.
This guide will show you the necessary steps to convert a brand new project build scripts to use Kotlin.
Here we’ll use the Empty Views Activity
template but the steps are easily adaptable.
Switching to Kotlin
Most changes are syntax related, luckily Groovy’ syntax can be compatible with that of Kotlin.
Overall switching to Kotlin is applying the same 4 steps process:
- Using Find and Replace to change all
'
(single quote) with"
(double quote) - Adding explicit parentheses to function calls and equal signs to assignments
- Renaming the file to add
.kts
at the end - Fixing the names of variables that differs between Groovy and Kotlin and add some explicit cast (mostly for
uri
)
The second step is the hardest since you don’t really have a clear way of knowing which are functions and which are variables beforehand. So we’re going to show this on a concrete example.
Concrete Example
We have a brand new project from the Empty Views Activity
template.
Let us start with settings.gradle
almost all lines are function calls with explicit parentheses and even setting the root project’s name use double quotes.
The only line that needs modification is the last one. It needs to be changed from include ':app'
to include(":app")
, so we convert the single quotes into double and add the explicit parentheses for the include
function.
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "Woosmap Demo"
include ':app'
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "Woosmap Demo"
include(":app")
Next we move onto the project’s build.gradle
.
First let’s start by using the editor’s Find & Replace to change all the single quotes into double.
We then need to add explicit parentheses however in this specific case they are needed only for the id
function which takes only one String argument.
So a line like id 'com.android.application' version '8.0.2' apply false
becomes id("com.android.application") version "8.0.2" apply false
.
That’s because both version
and apply
are infix functions but you can add parentheses to them both if you wish.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.0.2' apply false
id 'com.android.library' version '8.0.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.22' apply false
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.0.2" apply false
id("com.android.library") version "8.0.2" apply false
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
}
Last but not least we take on the module-level build.gradle
of the app.
Again use Find & Replace to change single quotes in double.
The first block is plugins
which is the same as the one we saw just before in the project’s build.gradle
.
So do the same and add explicit parentheses for the id
functions.
At the end of the file you should have a dependencies
block, it only contains function calls so add explicit parentheses to implementation
, testImplementation
and androidTestImplementation
.
Finally for the android
block and sub-blocks almost everything are variables assignments, add explicit =
equal sign to everything.
EXCEPT for the proguardFiles
, by default it’s the only function call there is in this example hence it needs explicit parentheses around all arguments.
The last line that needs modification is minifyEnabled false
, most boolean flags with the Kotlin plugin’s interface exist with the prefix is
, so change it to isMinifyEnabled = false
.
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.example.woosmapdemo'
compileSdk 33
defaultConfig {
applicationId "com.example.woosmapdemo"
minSdk 27
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "com.example.woosmapdemo"
compileSdk = 33
defaultConfig {
applicationId = "com.example.woosmapdemo"
minSdk = 27
targetSdk = 33
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
Now that all our files are changed we need to add .kts
to theirs filenames in order for Android Studio and Gradle to interpret them using Kotlin.
Renaming them while Android Studio is open might cause problem, so it’s better to close it completely before renaming all files and then reopen it so it can start fresh.