小伙快把你的Gradle从Groovy搬迁到KTS

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)

小伙快把你的Gradle从Groovy迁移到KTS

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 文档中的字符串模板。

小伙快把你的Gradle从Groovy迁移到KTS

8.重命名文件扩展名

请在搬迁每个 build 文件的内容时将 .kts 增加到其文件扩展名后。例如,选择一个 build 文件(如 settings.gradle 文件)。将该文件重命名为 settings.gradle.kts,然后将其内容转化为 KTS。请确保您的项目在搬迁每个 build 文件之后仍然能够编译。

请先搬迁最小的文件以便堆集经验,然后再持续。项目中能够混合运用 KTS 和 Groovy build 文件,因此您无需着急,能够小心细致地进行搬迁。

def 替换为 valvar

def 替换为 valvar,这是在 Kotlin 中界说变量的方法。以下是 Groovy 中的变量声明:

9.把app的build.gradle改成build.gradle.kts:

报错信息如下:

小伙快把你的Gradle从Groovy迁移到KTS

依据官网的规矩修正如下:

小伙快把你的Gradle从Groovy迁移到KTS

小伙快把你的Gradle从Groovy迁移到KTS

小伙快把你的Gradle从Groovy迁移到KTS

10.完好的装备如下:

plugins {
  id ("com.android.application")
  id ("org.jetbrains.kotlin.android")
}
​
android {
  namespace = ("com.example.dropdowncomposedemo")
  compileSdk = 33
​
  defaultConfig {
    applicationId = ("com.example.dropdowncomposedemo")
    minSdk = 23
    targetSdk = 33
    versionCode = 1
    versionName = "1.0"testInstrumentationRunner = ("androidx.test.runner.AndroidJUnitRunner")
    vectorDrawables {
      useSupportLibrary = true
     }
   }
​
  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")
   }
  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("androidx.compose.ui:ui:1.2.0")
  implementation("androidx.compose.ui:ui-tooling-preview:1.2.0")
  implementation("androidx.compose.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("androidx.compose.ui:ui-test-junit4:1.2.0")
  debugImplementation("androidx.compose.ui:ui-tooling:1.2.0")
  debugImplementation("androidx.compose.ui:ui-test-manifest:1.2.0")
}

11.改完之后验证一下装备:

小伙快把你的Gradle从Groovy迁移到KTS

12.修正setting.gradle为setting.gradle.kts:

小伙快把你的Gradle从Groovy迁移到KTS

发现改完后又报错了,依据错误提示修正后的装备如下:

小伙快把你的Gradle从Groovy迁移到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 ("https://maven.aliyun.com/nexus/content/repositories/releases/")
​
   }
  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 false
  id("com.android.library") version "7.4.1" apply false
  // 声明kotlin 1.7.30  插件版别 可是并不直接引进
  kotlin("jvm") version "1.7.0" apply false
}

小伙快把你的Gradle从Groovy迁移到KTS

14.统一管理依靠库:

新建一个build.src目录

小伙快把你的Gradle从Groovy迁移到KTS

15.增加kotlin-dsl插件:

小伙快把你的Gradle从Groovy迁移到KTS

16.新建一个名为libs的库管理类:

import java.text.SimpleDateFormat
​
object 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 = 29
  const val buildToolsVersion = "30.0.2"
  const val minAndroidSdk = 21
  const val targetSdk = 29
  const val versionCode = 1
  const val versionName = "1.0.0"
​
  val dateFormat: String = SimpleDateFormat("HHmm").format(System.currentTimeMillis())
​
  //libs version
  const 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 libs
  const 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 = "androidx.compose.ui:ui:$androidx_compose_ui_version"
  const val ui_tooling_preview = "androidx.compose.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 = "androidx.compose.ui:$androirx_ui_test_junit4_version"
  const val ui_tooling = "androidx.compose.ui:ui-tooling:$android_ui_tooling_version"
  const val ui_test_manifest = "androidx.compose.ui:ui-test-manifest:$android_ui_test_manifest_version"
}

小伙快把你的Gradle从Groovy迁移到KTS

小伙快把你的Gradle从Groovy迁移到KTS

小伙快把你的Gradle从Groovy迁移到KTS

17.修正新的依靠引进方法:

两种引进方法:

17.1.只修正依靠版别的引进:

小伙快把你的Gradle从Groovy迁移到KTS

17.2.修正整个依靠库的引进:

小伙快把你的Gradle从Groovy迁移到KTS

18.运转修正后的装备作用:

小伙快把你的Gradle从Groovy迁移到KTS

小伙快把你的Gradle从Groovy迁移到KTS

19.总结:

虽然搬迁时遇到许多问题,可是依据官方文档和各种资料仍是一步步渐渐处理了,能够说是进程充满曲折和崎岖,刚开始不熟悉装备,统一管理版别时遇到各种问题,最终发现是kotlin、compose和gradle版别不统一,有点大意导致引进依靠库的姓名写错了,一向以为是vpn的问题,可是我翻开自己购买的软件重新构建仍是失利,最终调试了半天才发现是依靠库引进的姓名和官网的对不上,导致一向构建失利,许多库都没下载成功,小伙伴们必定不能学我大意大意,这种问题其实很简单就是当时没发现,前面道路险且难,需要一向砥砺前行,如果感兴趣的小伙伴能够自己去试试,后边会把项目渐渐测验转化成dsl语法,界面、网络恳求等等。

20.项目源码地址:在dev_dsl分支

gitee.com/jackning_ad…