Android支持使用Kotlin DSL来构建Gradle脚本了,还不赶紧学习一波?
本文主题:
1.如何使用Kotlin DSL替换Groovy
2.过程中遇到的问题以及解决方法
使用Kotlin DSL 的优势:
Kotlin DSL的劣势:
Gradle 版本: 3.5.3
gradle-wrapper版本:5.6.4
我们以一个新的Android项目为例,一步步从groovy迁移到Kotlin DSL
把setting.gradle
重命名为 setting.gradle.kts
所有的Kotlin DSL 文件,都是以.kts 为文件名后缀
然后修改文件里面的内容:
include (":app")
rootProject.buildFileName = "build.gradle.kts"
这里做的事情也很简单,就是把原本的 “:” 改成了 “()” 这也是Kotlin DSL和Groovy语法的差别之一。
把build.gradle
重命名为 build.gradle.kts
然后修改内容:
buildscript {
val kotlin_version = "1.3.61" // #1
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:4.0.0-beta01") // #2
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
tasks.register("clean", Delete::class) { // #3
delete(rootProject.buildDir)
}
这里主要修改的就是三点,我已经在代码中标识出来了:
同样的,首先把build.gradle
重命名为 build.gardle.kts
这里需要做的变动就比较多了,直接上修改后的代码:
plugins { // #1
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
}
android {
compileSdkVersion(29) // #2
buildToolsVersion("29.0.3")
defaultConfig {
applicationId = "com.bluelzy.kotlindsldemo"
minSdkVersion(21)
targetSdkVersion(29)
versionCode = 1
versionName = "1.0"
}
buildTypes {
getByName("release") { // #3
isMinifyEnabled = false
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
dependencies {
implementation(
fileTree( // #4
mapOf(
"dir" to "libs", "include" to listOf("*.jar")
)
)
)
implementation (kotlin(
"stdlib-jdk7",
org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION
))
implementation("androidx.core:core-ktx:1.2.0")
implementation("androidx.appcompat:appcompat:1.1.0")
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
testImplementation("junit:junit:4.12")
androidTestImplementation("androidx.test.ext:junit:1.1.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")
}
需要注意的地方同样在注释中标识出来了:
完成了这几步之后,我们就可以点击sync project,如无意外的话应该是可以成功的,到目前为止其实我们就已经从Groovy成功迁移到了Kotlin DSL了。但是大家有没有发现一个问题,就是现在我们所有的版本号,依赖版本,TargetSDK等等,都是直接写在build.gradle.kts文件中的,能不能把这些变量都统一放到一个地方管理呢?特别是多个Module的时候,我们希望只要改动一个地方,所有的依赖都能够同步。
其实官方已经给我们提供了一个解决方案了,那就是使用buildSrc
在根目录下创建一个buildSrc文件夹,也就是和app文件夹同一等级。创建后的结果应该是这样的:
大家可以先忽略Kotlin文件夹里面的3个文件。只要创建了src/main/kotlin 以及 build.gradle.kts 文件就可以了。
接下来就要修改build.gradle.kts
文件了:
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
解释一下,这一个buildSrc文件夹的作用是什么呢?
官方推荐我们使用这个文件夹来管理整个项目的依赖,也就是说,我们可以在这个路劲定义多个和依赖相关的类。
object Apps {
const val compileSdk = 29
const val minSdk = 21
const val targetSdk = 29
const val versionCode = 1
const val versionName = "1.0.0"
}
object Versions {
const val gradle = "3.5.3"
const val kotlin = "1.3.61"
const val appcompat = "1.0.2"
/* test */
const val junit = "4.12"
}
object Libs {
const val kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
}
object TestLibs {
const val junit = "junit:junit:${Versions.junit}"
}
举个例子,我们在这个kt文件中定义了三个单例,分别用于存放App相关的版本号,依赖相关的版本号,以及依赖包的名称
然后我们就可以在App的build.gradle.kts里面用上这些定义的常量了
更新后的build.gradle.kts:
// 省略代码
android {
compileSdkVersion(Apps.compileSdk)
defaultConfig {
applicationId = "com.bluelzy.kotlindsldemo"
minSdkVersion(Apps.minSdk)
targetSdkVersion(Apps.targetSdk)
versionCode = Apps.versionCode
versionName = Apps.versionName
}
// 省略代码
}
dependencies {
// android supports
implementation(Libs.appcompat)
// test
testImplementation(TestLibs.junit)
}
上面的文件并不是完整的,大家可以自己按照项目里的依赖添加到Dependencies.kt文件,以及更新build.gradle.kts文件即可。
如果项目有多个Modlue,而且依赖关系也很复杂,那么我们可以在buildSrc/src/main/kotlin 目录下多定义几个kt文件,用于管理不同的依赖。这里就不展开了。
其实使用Kotlin DSL来替代Groovy的步骤比较简单,就是把3个gradle相关的文件重命名为.kts,然后用Kotlin的语法修改,最后在buildSrc目录下创建依赖相关的kt文件。
但是在这个过程中同样会遇到一些问题,以我个人遇到的问题为例
1.项目能build成功,也可以正常运行,但是在App的build.gradle.kts文件中 android
标签和 implementation
一直报错,重启AS,clean project,还有清除缓存都无法解决问题。
如果出现这个问题的话,大家可以尝试修改gradle的版本,我一开始创建的项目使用的gradle版本是:
gradle: 4.0.0-beta01
gradle-wrapper: https://services.gradle.org/distributions/gradle-6.1.1-all.zip
可能是新版本的Bug,怎么都找不到android
后面我就把gradle降级为:
Gradle 版本: 3.5.3
gradle-wrapper版本:5.6.4
然后就可以了
2.在修改build.gradle.kts文件的过程中会报错,这个时候大家可以打开Gradle面板,找到里面的build setup
选项,运行init
最后附上一张使用了Kotlin DSL的build.gradle.kts文件截图,是不是比之前清晰多了呢?
Gradle 中文官方文档
The New Way of Writing Build Gradle with Kotlin DSL
使用Kotlin DSL的Github项目 - showCase