逐步指南将Android Project的Gradle脚本从Groovy脚本转换或迁移到Kotlin脚本(KTS)
介绍
Gradle是构建自动化工具。 Android Studio使用Gradle来构建应用程序。 Gradle可以用这两种域特定语言(DSL)写入:
-
groovy脚本
-
kotlin脚本(kts)
什么是格鲁维?
groovy是一种动态键入的语言,这意味着变量类型在运行时已知。这通常是翻译或脚本语言。
什么是科特林?
kotlin是一种静态类型的语言,这意味着变量类型在编译时已知。这通常用于通用编程语言。但是,对于这种Gradle构建环境,Kotlin被视为脚本。它称为Kotlin脚本(KTS)
Groovy和Kotlin都可以在Java Virtual Machine(JVM)上运行。
为什么要将Groovy转换为KTS?
这就是official documentation所说的:
将来,KTS优先于Groovy编写Gradle脚本,因为Kotlin更可读,并提供更好的编译时间检查和IDE支持。
,但它也说:
使用kts构建往往比使用Groovy
构建较慢
在我看来,还没有准备好吗?这可能就是为什么Android Studio的默认Gradle脚本设置为Groovy而不是KTS的原因。
如果构建性能不是问题,也许您可以考虑迁移到KTS?但是谁不想更快地构建?
所以我认为转换为KTS可能是出于教育目的或为未来做准备。以下指南提供了有关将my template app转换为使用KTS的分步说明。
分步指南
-
*.gradle
扩展名用于groovy脚本 -
*.gradle.kts
扩展名用于kotlin脚本。
1.重命名设置。
您会收到以下错误。
函数调用'包括(...)'预期
为了解决这个问题,您可以更改
include ':app'
include ("app")
您在IDE的顶部收到此消息。
多个脚本定义适用于此脚本。 Kotlinsettingscript使用
它看起来像一个known issue,但它不是一个表演者。
您还会收到此消息,该消息将在您将所有Groovy脚本转换为KTS之后会消失。
代码洞察力不可用(未收到脚本配置) - 添加到独立脚本
2.重命名build.gradle to build.gradle.kts
您会收到此错误:
意外的令牌(使用';'在同一行上分开表达式)
为了解决这个问题,您可以更改
task clean(type: Delete) {
delete rootProject.buildDir
}
tasks {
register("clean", Delete::class) {
delete(rootProject.buildDir)
}
}
[更新 - 2023年1月3日]:看起来不再需要这种“干净”任务,因为默认情况下它已在Gradle中实现。因此,我在build.gradle / build.gradle.kts。< / p>中删除了此任务。< / p>
之后,您编译并获得相同的错误:
意外的令牌(使用';'在同一行上分开表达式)
要解决这个问题,您替换
buildscript {
ext {
android_gradle_plugin_version = '7.2.2'
}
}
plugins {
id 'com.android.application' version "$android_gradle_plugin_version" apply false
id 'com.android.library' version "$android_gradle_plugin_version" apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
}
与
buildscript {
val android_gradle_plugin_version by extra("7.2.2")
}
plugins {
id("com.android.application") version "${extra["android_gradle_plugin_version"]}" apply false
id("com.android.library") version "${extra["android_gradle_plugin_version"]}" apply false
id("org.jetbrains.kotlin.android") version "1.7.0" apply false
}
它可以成功构建和运行。但是,仍然有此错误消息:
val extensionaware.extra:在此上下文中无法通过隐式接收器调用副植物外部。如有必要,请使用显式
看起来这是plugins DSL limitations - constrained syntax,它不允许您访问插件块中的变量 - 不支持任意代码。
插件{}块不支持任意代码。它受到约束...
所以只是硬代码:
buildscript {
}
plugins {
id("com.android.application") version "7.2.2" apply false
id("com.android.library") version "7.2.2" apply false
id("org.jetbrains.kotlin.android") version "1.7.0" apply false
}
fyi-我在这里没有
compose_version
变量,因为我已经将其移至app\build.gradle
3.重命名app \ build.gradle到app \ build.gradle.kts
如果您使用"Refactor -> Rename...",它会自动更新proguard-rules.pro
文件中的注释。
您会发现错误,这是修复程序。
更改插件
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
plugins {
id ("com.android.application")
id ("org.jetbrains.kotlin.android")
}
更改编译SDK和DefaultConfig
android {
compileSdk 32
defaultConfig {
applicationId "vtsen.hashnode.dev.newemptycomposeapp"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
/*...*/
}
android {
compileSdk = 32
defaultConfig {
applicationId = "vtsen.hashnode.dev.newemptycomposeapp"
minSdk = 21
targetSdk = 32
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
/*...*/
}
更改构建类型和组合
android {
/*...*/
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
/*...*/
}
android {
/*...*/
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
/*...*/
}
注意:
minifyEnabled
被更名为isMinifyEnabled
更改构建功能和组合
android {
/*...*/
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.2.0'
}
/*...*/
}
android {
/*...*/
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.2.0"
}
/*...*/
}
更改包装和名称空间
android {
/*...*/
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
namespace 'vtsen.hashnode.dev.newemptycomposeapp'
}
android {
/*...*/
packagingOptions {
resources {
excludes.add("/META-INF/{AL2.0,LGPL2.1}")
}
}
namespace = "vtsen.hashnode.dev.newemptycomposeapp"
}
变化依赖性
dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.activity:activity-compose:1.5.1'
def compose_version = '1.2.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$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"
}
dependencies {
implementation("androidx.core:core-ktx:1.8.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1")
implementation("androidx.activity:activity-compose:1.5.1")
val composeVersion = "1.2.1"
implementation("androidx.compose.ui:ui:$composeVersion")
implementation("androidx.compose.material:material:$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
用于kotlin中的命名约定而不是compose_version
建立时间比较
我执行快速建立时间测试,差异并不显着。两个构建时间大致相同。这个项目可能太简单了,因此差异并不明显。
建立时间 | 第一个编译(清洁构建) | 第二章(清洁构建) |
---|---|---|
groovy | 6秒 | 2-3秒 |
kts | 6秒 | 2-3秒 |
源代码
-
github存储库:Demo_CleanEmptyCompose
-
转换:Diff
s。
最初出版于https://vtsen.hashnode.dev 。