小伙快把你的Android从Groovy迁移到DSL"/>
小伙快把你的Android从Groovy迁移到DSL
文章目录
- 小伙快把你的Android从Groovy迁移到DSL
- 1.概念解释
- 2.Groovy和KTS对比
- 3.优点:
- 4.缺点和已知问题:
- 5.脚本文件命名
- 6.转换语法差异:
- 为方法调用添加圆括号
- 7.转换字符串
- 8.重命名文件扩展名
- 将 `def` 替换为 `val` 或 `var`
- 9.把app的build.gradle改成build.gradle.kts:
- 10.完整的配置如下:
- 11.改完之后验证一下配置:
- 12.修改setting.gradle为setting.gradle.kts:
- 13.修改项目的build.gradle为build.gradle.kts:
- 14.统一管理依赖库:
- 15.添加kotlin-dsl插件:
- 16.新建一个名为libs的库管理类:
- 17.修改新的依赖引入方式:
- 17.1.只修改依赖版本的引入:
- 17.2.修改整个依赖库的引入:
- 18.运行修改后的配置效果:
- 19.总结:
- 20.项目源码地址:在dev_dsl分支
小伙快把你的Android从Groovy迁移到DSL
Kotlin 脚本 (KTS) 比 Groovy 更适合用于编写 Gradle 脚本,因为采用 Kotlin 编写的代码可读性更高,并且 Kotlin 提供了更好的编译时检查和 IDE 支持。Android Gradle 插件 4.0 支持在 Gradle build 配置中使用 KTS。
1.概念解释
- Gradle: 自动化构建工具. 平行产品:
Maven
. - Groovy: 语言, 编译后变为
JVM byte code
, 兼容Java
平台. - DSL:
Domain Specific Language
, 领域特定语言. - Groovy DSL:
Gradle
的API是Java的,Groovy DSL
是在其之上的脚本语言.Groovy DS
脚本文件后缀:.gradle
. - KTS:是指 Kotlin 脚本,这是 Gradle 在构建配置文件中使用的一种 Kotlin 语言形式。Kotlin 脚本是可从命令行运行的 Kotlin 代码。
- Kotlin DSL:主要是指 Android Gradle 插件 Kotlin DSL,有时也指底层 Gradle Kotlin DSL。
在讨论从 Groovy 迁移时,术语“KTS”和“Kotlin DSL”可以互换使用。换句话说,“将 Android 项目从 Groovy 转换为 KTS”与“将 Android 项目从 Groovy 转换为 Kotlin DSL”实际上是一个意思。
2.Groovy和KTS对比
类型 | Kotlin | Groovy |
---|---|---|
自动代码补全 | 支持 | 不支持 |
是否类型安全 | 是 | 不是 |
源码导航 | 支持 | 不支持 |
重构 | 自动关联 | 手动修改 |
3.优点:
- 可以使用
Kotlin
, 开发者可能对这个语言更熟悉更喜欢. IDE
支持更好, 自动补全提示, 重构,imports
等.- 类型安全:
Kotlin
是静态类型. - 不用一次性迁移完: 两种语言的脚本可以共存, 也可以互相调用.
4.缺点和已知问题:
- 目前,采用
KTS
的构建速度可能比采用Groovy
慢。 Project Structure
编辑器不会展开在buildSrc
文件夹中定义的用于库名称或版本的常量。KTS
文件目前在项目视图中不提供文本提示。
5.脚本文件命名
脚本文件扩展名取决于编写 build 文件所用的语言:
- 用 Groovy 编写的 Gradle build 文件使用
.gradle
文件扩展名。 - 用 Kotlin 编写的 Gradle build 文件使用
.gradle.kts
文件扩展名。
6.转换语法差异:
Groovy 和 Kotlin 的语法之间存在一些普遍差异,因此您需要在 build 脚本中应用以下更改。
为方法调用添加圆括号
提示:首先,在更改文件扩展名之前,最好先在 Groovy 代码中添加圆括号。这样可以更轻松地转换为 Kotlin。
Groovy 允许您在方法调用中省略圆括号,而 Kotlin 则要求使用圆括号。如需迁移配置,请为这些类型的方法调用添加圆括号。以下代码展示了如何在 Groovy 中配置设置:
compileSdkVersion 30
以下是使用 Kotlin 编写的相同代码:
compileSdkVersion(30)
7.转换字符串
以下是 Groovy 和 Kotlin 在字符串方面的差异:
-
用于定义字符串的双引号:虽然 Groovy 允许使用单引号来定义字符串,但 Kotlin 要求使用双引号。
-
基于句点表达式的字符串插值:在 Groovy 中,对于句点表达式的字符串插值,您可以仅使用“
$
”前缀,但 Kotlin 要求您用大括号将句点表达式括起来。没转换前的字符串都是单引号:
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'composeOptions {kotlinCompilerExtensionVersion '1.4.2'}packagingOptions {resources {excludes += '/META-INF/{AL2.0,LGPL2.1}'}
不过,转换后,上述代码都是双引号
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'composeOptions {kotlinCompilerExtensionVersion = ("1.2.0")}packagingOptions {resources {excludes += ("/META-INF/{AL2.0,LGPL2.1}")}}
如需了解详情,请参阅 Kotlin 文档中的字符串模板。
8.重命名文件扩展名
请在迁移每个 build 文件的内容时将 .kts
添加到其文件扩展名后。例如,选择一个 build 文件(如 settings.gradle
文件)。将该文件重命名为 settings.gradle.kts
,然后将其内容转换为 KTS。请确保您的项目在迁移每个 build 文件之后仍然可以编译。
请先迁移最小的文件以便积累经验,然后再继续。项目中可以混合使用 KTS 和 Groovy build 文件,因此您无需着急,可以小心细致地进行迁移。
将 def
替换为 val
或 var
将 def
替换为 val
或 var
,这是在 Kotlin 中定义变量的方式。以下是 Groovy 中的变量声明:
9.把app的build.gradle改成build.gradle.kts:
报错信息如下:
根据官网的规则修改如下:
10.完整的配置如下:
plugins {id ("com.android.application")id ("org.jetbrains.kotlin.android")
}android {namespace = ("com.example.dropdowncomposedemo")compileSdk = 33defaultConfig {applicationId = ("com.example.dropdowncomposedemo")minSdk = 23targetSdk = 33versionCode = 1versionName = "1.0"testInstrumentationRunner = ("androidx.test.runner.AndroidJUnitRunner")vectorDrawables {useSupportLibrary = true}}buildTypes {release {//minifyEnabled = falseproguardFiles (getDefaultProguardFile ("proguard-android-optimize.txt"), "proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_1_8targetCompatibility = JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = ("1.8")}buildFeatures {compose = true}composeOptions {kotlinCompilerExtensionVersion = ("1.2.0")}packagingOptions {resources {excludes += ("/META-INF/{AL2.0,LGPL2.1}")}}
}dependencies {implementation("androidx.core:core-ktx:1.7.0")implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.3.1")implementation("androidx.activity:activity-compose:1.3.1")implementation("androidxpose.ui:ui:1.2.0")implementation("androidxpose.ui:ui-tooling-preview:1.2.0")implementation("androidxpose.material:material:1.2.0")testImplementation("junit:junit:4.13.2")androidTestImplementation("androidx.test.ext:junit:1.1.5")androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")androidTestImplementation("androidxpose.ui:ui-test-junit4:1.2.0")debugImplementation("androidxpose.ui:ui-tooling:1.2.0")debugImplementation("androidxpose.ui:ui-test-manifest:1.2.0")
}
11.改完之后验证一下配置:
12.修改setting.gradle为setting.gradle.kts:
发现改完后又报错了,根据错误提示修改后的配置如下:
pluginManagement {repositories {google()mavenCentral()gradlePluginPortal()}
}
dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()mavenCentral()}
}
rootProject.name = "DropDownComposeDemo"
include (":app")
13.修改项目的build.gradle为build.gradle.kts:
val compose_ui_version = ("1.2.0")
// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {repositories {google()mavenCentral()maven ("/")}dependencies {classpath ("com.android.tools.build:gradle:7.4.1")classpath (kotlin("gradle-plugin", version = "1.7.0"))// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}plugins {id("com.android.application") version "7.4.1" apply falseid("com.android.library") version "7.4.1" apply false// 声明kotlin 1.7.30 插件版本 但是并不直接引入kotlin("jvm") version "1.7.0" apply false
}
14.统一管理依赖库:
新建一个build.src目录
15.添加kotlin-dsl插件:
16.新建一个名为libs的库管理类:
import java.text.SimpleDateFormatobject libs {const val StoreFile = "../"const val StorePassword = "123456"const val KeyAlias = ""const val KeyPassword = "123456"const val namespace = "com.example.dropdowncomposedemo"const val applicationId = "com.example.dropdowncomposedem"const val compileSdkVersion = 29const val buildToolsVersion = "30.0.2"const val minAndroidSdk = 21const val targetSdk = 29const val versionCode = 1const val versionName = "1.0.0"val dateFormat: String = SimpleDateFormat("HHmm").format(System.currentTimeMillis())//libs versionconst val agp_version = "7.4.1"const val kotlin_version = "1.7.0"const val ksp_verion = "$agp_version-1.0.6"const val kotlinx_coroutines_version = "1.3.9"const val lifecycle_version = "2.2.0"const val room_version = "2.2.6"const val work_version = "2.4.0"const val retrofit_version = "2.9.0"const val moshi_version = "1.11.0"const val fragment_version = "1.2.5"const val status_bar_util_version = "1.5.1"const val glide_version = "4.11.0"const val transformations_version = "4.0.0"const val core_ktx_version = "1.7.0"const val appcompat_version = "1.6.0"const val material_version = "1.4.2"const val constraintlayout_version = "2.1.4"const val espresso_core_version = "3.5.1"const val lifecycle_runtime_ktx_version = "2.3.1"const val activity_compose_version = "1.3.1"const val androidx_compose_ui_version = "1.4.0"const val androidx_ui_tooling_preview = "1.4.0"const val junit_version = "4.13.2"const val androidx_test_junit_version = "1.1.5"const val androirx_ui_test_junit4_version = "1.4.0"const val android_ui_tooling_version = "1.4.0"const val android_ui_test_manifest_version = "1.4.0"//android libsconst val androidx_appcompat = "androidx.appcompat:appcompat:$appcompat_version"const val com_google_android_material = "com.google.android.material:material$material_version"const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout$constraintlayout_version"const val androidx_espresso_core = "androidx.test.espresso:espresso-core$espresso_core_version"const val kotlinx_coroutines_core = "org.jetbrains.kotlinx:kotlinx-coroutines-core$kotlinx_coroutines_version"const val core_ktx = "androidx.core:core-ktx:$core_ktx_version"const val activity_compose = "androidx.activity:activity-compose:$activity_compose_version"const val lifecycle_runtime = "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_runtime_ktx_version"const val compose_ui = "androidxpose.ui:ui:$androidx_compose_ui_version"const val ui_tooling_preview = "androidxpose.ui:ui-tooling-preview:$androidx_ui_tooling_preview"const val junit = "junit:junit:$junit_version"const val androidx_test_junit = "androidx.test.ext:junit:$androidx_test_junit_version"const val androidx_ui_test_junit4 = "androidxpose.ui:$androirx_ui_test_junit4_version"const val ui_tooling = "androidxpose.ui:ui-tooling:$android_ui_tooling_version"const val ui_test_manifest = "androidxpose.ui:ui-test-manifest:$android_ui_test_manifest_version"
}
17.修改新的依赖引入方式:
两种引入方式:
17.1.只修改依赖版本的引入:
17.2.修改整个依赖库的引入:
18.运行修改后的配置效果:
19.总结:
虽然迁移时遇到很多问题,但是根据官方文档和各种资料还是一步步慢慢解决了,可以说是过程充满曲折和坎坷,刚开始不熟悉配置,统一管理版本时遇到各种问题,最后发现是kotlin、compose和gradle版本不统一,有点粗心导致引入依赖库的名字写错了,一直以为是vpn的问题,可是我打开自己购买的软件重新构建还是失败,最后调试了半天才发现是依赖库引入的名字和官网的对不上,导致一直构建失败,很多库都没下载成功,遇到问题不要慌,慢慢找到原因和解决方法就好,前面道路险且难,需要一直砥砺前行,如果感兴趣的小伙伴可以自己去试试,后面会把项目慢慢尝试转换成dsl语法。
20.项目源码地址:在dev_dsl分支
更多推荐
小伙快把你的Android从Groovy迁移到DSL
发布评论