Using Kotlin for Gradle

Learn how to convert your Gradle scripts from Groovy to Kotlin

  1. Advantages
  2. Switching to Kotlin
  3. Concrete Example

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:

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.

Was this article helpful?
Have more questions? Submit a request