The right way to Convert Android Gradle Groovy to KTS?


Introduction

Gradle is the construct automation instrument. Android Studio makes use of Gradle to construct the apps. Gradle could be written in these 2 domain-specify languages (DSL):

  • Groovy Script

  • Kotlin Script (KTS)

What’s Groovy?

Groovy is a dynamically typed language, which suggests the variable sorts are identified at run time. That is normally an interpreter or scripting language.

What’s Kotlin?

Kotlin is a statically typed language, which suggests the variable sorts are identified at compile time. That is normally for general-purpose programming language. Nevertheless, for this Gradle constructing context, Kotlin is taken into account as a script. It’s referred to as Kotlin Script (KTS)

Each Groovy and Kotlin can run on Java Digital Machine (JVM).

Why Convert Groovy to KTS?

That is what official documentation says:

Sooner or later, KTS might be most well-liked over Groovy for writing Gradle scripts as a result of Kotlin is extra readable and presents higher compile-time checking and IDE assist.

Nevertheless it additionally says:

builds utilizing KTS are typically slower than builds utilizing Groovy

It sounds to me, it’s not prepared but? In all probability that is the rationale why the default Gradle script setup from Android Studio is Groovy and never KTS.

If construct efficiency will not be a problem, perhaps you possibly can contemplate migrating to KTS? However who does not desire a sooner construct?

So I believe conversion to KTS might be for schooling functions or getting ready your self for the long run. The next information offers step-by-step directions on what I did to transform my template app to make use of KTS.

Step-by-step Information

1. Rename settings.gradle to settings.gradle.kts

You get the next error.

Perform invocation ’embrace(…)’ anticipated

To repair that, you alter

embrace ':app'

to

embrace ("app")

You get this message on the highest of your IDE.

A number of script definitions are relevant to this script. KotlinSettingScript is used

It seems to be like a identified problem, however it’s not a show-stopper.

You even have this message which might be gone after you change all of the Groovy scripts to KTS.

Code perception unavailable (script configuration wasn’t acquired) – Add to standalone scripts

2. Rename construct.gradle to construct.gradle.kts

You get this error:

Surprising tokens (use ‘;’ to separate expressions on the identical line)

To repair that, you alter

job clear(kind: Delete) {
    delete rootProject.buildDir
}

to

duties {
    register("clear", Delete::class) {
        delete(rootProject.buildDir)
    }
}

After that, you compile and get the identical error:

Surprising tokens (use ‘;’ to separate expressions on the identical line)

To repair that, you exchange

buildscript {
    ext {
        android_gradle_plugin_version = '7.2.2'
    }
}

plugins {
    id 'com.android.software' model "$android_gradle_plugin_version" apply false
    id 'com.android.library' model "$android_gradle_plugin_version" apply false
    id 'org.jetbrains.kotlin.android' model '1.7.0' apply false
}

with

buildscript {
    val android_gradle_plugin_version by further("7.2.2")
}

plugins {
    id("com.android.software") model "${further["android_gradle_plugin_version"]}" apply false
    id("com.android.library") model "${further["android_gradle_plugin_version"]}" apply false
    id("org.jetbrains.kotlin.android") model "1.7.0" apply false
}

It could construct and run efficiently. Nevertheless, there may be nonetheless this error message:

val ExtensionAware.further: ExtraPropertiesExtension’ cannot be referred to as on this context by implicit receiver. Use the express one if mandatory

It seems to be like that is plugins DSL limitations – constrained syntax which does not mean you can entry the variable within the plugins block – doesn’t assist arbitrary code.

The plugins {} block doesn’t assist arbitrary code. It’s constrained…

So simply arduous code it as a substitute:

buildscript {
}

plugins {
    id("com.android.software") model "7.2.2" apply false
    id("com.android.library") model "7.2.2" apply false
    id("org.jetbrains.kotlin.android") model "1.7.0" apply false
}

FYI – I haven’t got the compose_version variable right here as a result of I’ve moved it to the appbuild.gradle

3. Rename appbuild.gradle to appbuild.gradle.kts

Should you use the “Refactor -> Rename…”, it mechanically updates the remark in proguard-rules.professional file.

You’re going to get errors, and listed here are the fixes.

Change plugins

plugins {
    id 'com.android.software'
    id 'org.jetbrains.kotlin.android'
}

to

plugins {
    id ("com.android.software")
    id ("org.jetbrains.kotlin.android")
}

Change compile Sdk & defaultConfig

android {
    compileSdk 32

    defaultConfig {
        applicationId "vtsen.hashnode.dev.newemptycomposeapp"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.check.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary true
        }
    }
    
}

to

android {
    compileSdk = 32

    defaultConfig {
        applicationId = "vtsen.hashnode.dev.newemptycomposeapp"
        minSdk = 21
        targetSdk = 32
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.check.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary = true
        }
    }
    
}

Change buildTypes and compleOptions

android {
    
    buildTypes {
        launch {
            minifyEnabled false
            proguardFiles getDefaultProguardFile(
                'proguard-android-optimize.txt'), 
                    'proguard-rules.professional'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    
}

to

android {
    
    buildTypes {
        launch {
            isMinifyEnabled  = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                    "proguard-rules.professional")
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    
}

Observe: minifyEnabled is renamed to isMinifyEnabled

Change buildFeatures and composeOptions

android {
    
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion '1.2.0'
    }
    
}

to

android {
    
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.2.0"
    }
    
}

**Change packaingOptions and namespace **

android {
    
    packagingOptions {  
        sources {  
            excludes += '/META-INF/{AL2.0,LGPL2.1}'  
        }  
    }

    namespace 'vtsen.hashnode.dev.newemptycomposeapp'
}

to

android {
    
    packagingOptions {  
        sources {  
            excludes.add("/META-INF/{AL2.0,LGPL2.1}")  
        }  
    }

    namespace = "vtsen.hashnode.dev.newemptycomposeapp"
}

Change dependencies

dependencies {
    implementation 'androidx.core:core-ktx:1.8.0'
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
    implementation 'androidx.exercise:activity-compose:1.5.1'

    def compose_version = '1.2.1'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.materials:materials:$compose_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"

    implementation "com.google.accompanist:accompanist-systemuicontroller:0.24.2-alpha"
}

to

dependencies {  

    implementation("androidx.core:core-ktx:1.8.0")  
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1")  
    implementation("androidx.exercise:activity-compose:1.5.1")  

    val composeVersion = "1.2.1"  
    implementation("androidx.compose.ui:ui:$composeVersion")  
    implementation("androidx.compose.materials:materials:$composeVersion")  
    implementation("androidx.compose.ui:ui-tooling-preview:$composeVersion")  
    debugImplementation("androidx.compose.ui:ui-tooling:$composeVersion") 

    implementation("com.google.accompanist:accompanist-systemuicontroller:0.24.2-alpha")  
}

composeVersion is used as a substitute of compose_version as a result of naming conference in Kotlin

Construct Time Comparisons

I carry out a fast built-time testing, the distinction will not be important. Each construct instances are about the identical. In all probability this undertaking is just too easy, so the distinction will not be apparent

Construct Time First Compile (clear construct) Second Compile (clear construct)
Groovy 6 seconds 2-3 seconds
KTS 6 seconds 2-3 seconds

Supply Code

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles