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 theappbuild.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 toisMinifyEnabled
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 ofcompose_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 |