Hello Geeks,
It’s been a while since Gradle released support for Kotlin scripts. We have been writing Gradle script in a language called Groovy since ages. Let’s be honest, We all know that Groovy sucks! Half of the times I have been like this when there’s an issue
Why does it needs -
- No Auto-Completion
- No Content Assist
- No Navigation to Source
- Don’t know what to write and how to write
Finally, We don’t have to learn Groovy for Gradle scripts. Now we can write our build scripts in Kotlin.
Kotlin script overcomes almost all the cons of Groovy
Added advantages over groovy (Old Pattern)
- Auto-Completion😎
- Content Assist😍
- Navigation to Source😱
- Kotlin Extensions support😘
- Errors at compile time instead of runtime💪
Sometimes it can be a bit messy to rewrite gradle.build into gradle.build.kts files, especially when all its cache is malfunctioning during that process.
Few times I had to reopen my project so that Android Studio can understand properly what is going on. “Refresh all Gradle projects” button has been life saver for me.
We talked about the pros n cons lets do migrate from build.gradle to build.gradle.kts file,
A nice thing about Kotlin build script is you don’t have to do the extra setup for enabling it. Just rename .gradle file to .gradle.kts file extension and Gradle will consider it as a Kotlin script.
Be with me we will easily convert the file in few steps which is highly recommended.
Note : To make sure that everything works fine, update your gradle to version 4.10 or higher. To do so, go to your project’s gradle-wrapper.properties and check distributionUrl for the current version. make sure it looks like below:
------------------- *************** ---------------------- ***************-----------------
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
------------------- *************** ---------------------- ***************-----------------
Step-1 Convert Settings.gradle File
Let’s start with settings.gradle file by renaming (Shift + F6) it to settings.gradle.kts. Now that this file is a Kotlin script, include will behave as a function and “:app” will be the string argument.
Before
include ':app'
After
include(":app")
✏️Note: that in Groovy, you were able to write single quotes(‘’) in place of double quotes(“”) but in Kotlin, you must have to use double quotes only.
Now that you have converted it in Kotlin, Gradle will identify it accordingly and will process it as Kotlin script. Just sync with Gradle files.
Step-2 Convert Project’s build.gradle File
Rename project level build.gradle to build.gradle.kts. The main difference here is in classpath and in clean task.
classpath is now a function in Kotlin which takes a string argument as shown below:
Before
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21"
}
After
dependencies {
classpath("com.android.tools.build:gradle:3.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21")
}
clean task will no longer be written in Groovy. This is how it looks in Kotlin:
Before
task clean(type: Delete) {
delete rootProject.buildDir
}
After
tasks.register("clean",Delete::class){
delete(rootProject.buildDir)
}
Another thing that can change is that if you have any repositories with url in repositories block. You can change it like this:
Before
repositories {
google()
jcenter()
maven{ url 'https://jitpack.io' }
}
After
repositories {
google()
jcenter()
maven { url = uri("https://jitpack.io") }
}
That’s it! The file is now completely in Kotlin. If you have some other configurations then you can easily convert it into Kotlin with the help of Auto Completion. If you don’t know how to implement something, you can always navigate to the source code. That’s the beauty of it.
Here is the whole build.gradle.kts file:
buildscript {
repositories {
maven { url = uri("https://jitpack.io") }
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21")
}
}
allprojects {
repositories {
google()
jcenter()
maven { url = uri("https://jitpack.io") }
}
}
tasks.register("clean",Delete::class){
delete(rootProject.buildDir)
}
You’ll be able to sync your project after completing this step.
Step-3 Convert App Level build.gradle File
Here comes a little bit messy part😵. Open app level build.gradle file and rename it to build.gradle.kts. Don’t try to sync now. It will show lots of errors but don’t worry, we’re going to remove all the errors one by one. Let’s start at the top.
In Groovy, every plugin was being applied individually whereas Kotlin provides plugins{} block to apply all the plugins within a single block.
Before
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
After
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
}
Here, id() and kotlin() are functions which are used to apply plugins.
id() is used to apply any plugin. All the plugins can be applied using id().
Plugins which are specific to Kotlin can also be applied using kotlin() function. That’s cool😎
Note that when you use kotlin() function, the kotlin prefix will be removed from plugin name and the dash(-) will be replaced by dot(.). For the sake of simplicity, you can use id() function instead.
The “android{ }” Block
Note these points to convert this block in Kotlin:
- compileSdkVersion is a function.
- applicationId is a property.
- minSdkVersion and targetSdkVersion are functions too.
- versionCode and versionName are properties again.
According to the above points, this block will look like this:
Before
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.birjuvachhani.gradlekotlindsldemo"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
...
...
}
After
android {
compileSdkVersion(28)
defaultConfig {
applicationId = "com.birjuvachhani.gradlekotlindsldemo"
minSdkVersion(19)
targetSdkVersion(28)
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
...
...
}
buildTypes{ } block is a bit tricky. A function getByName(String) is used to get a build type.
minifyEnabled is a property with name isMinifyEnabled.
proguardFiles and getDefaultProguardFile are functions.
This is how it will look like:
Before
android {
...
...
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
After
android {
...
...
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
The dependencies{ } Block
There should be only one block left (if you don’t have any extra configs hopefully😬) that is the dependencies{} block.
Here, implementation, kapt, api, testImplementation, androidTestImplementation, etc are functions.
The fileTree in implementation() is also a function which takes a map as an argument. Here’s how it will look like:
Before
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21"
implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
implementation 'androidx.core:core-ktx:1.1.0-alpha04'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.2-alpha01'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.2-alpha01'
}
After
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21")
implementation("androidx.appcompat:appcompat:1.1.0-alpha02")
implementation("androidx.core:core-ktx:1.1.0-alpha04")
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
testImplementation("junit:junit:4.12")
androidTestImplementation("androidx.test:runner:1.1.2-alpha01")
androidTestImplementation("androidx.test.espresso:espresso-core:3.1.2-alpha01")
}
Here is the whole app level build.gradle.kts file:
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
}
android {
compileSdkVersion(28)
defaultConfig {
applicationId = "com.birjuvachhani.gradlekotlindsldemo"
minSdkVersion(19)
targetSdkVersion(28)
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21")
implementation("androidx.appcompat:appcompat:1.1.0-alpha02")
implementation("androidx.core:core-ktx:1.1.0-alpha04")
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
testImplementation("junit:junit:4.12")
androidTestImplementation("androidx.test:runner:1.1.2-alpha01")
androidTestImplementation("androidx.test.espresso:espresso-core:3.1.2-alpha01")
}
Hell Yeah! Sync the project (Hopefully it will compile, let’s have some faith in Gradle). There you go, your project is converted in Kotlin build scripts. Say goodbye to Groovy!
Gradle will provide kotlin script support by default. That means this all will be directly generated for you. How amazing is that! Till then, Happy coding Friends!
Bonus: Well if you are not able to convert use this online tool if required:
https://gradle-kotlinize.web.app/
References: Strong thanks to Birju Vachhani, MindOrks,
https://docs.gradle.org/current/userguide/migrating_from_groovy_to_kotlin_dsl.html
Comments