前言
Android支持使用Kotlin DSL來構建Gradle腳本了,還不趕緊學習一波?
本文主題:
1.如何使用Kotlin DSL替換Groovy
2.過程中遇到的問題以及解決方法
爲什麼要使用Kotlin DSL
使用Kotlin DSL 的優勢:
- 由於現在Kotlin是Android官方推薦語言,因此使用Kotlin構建Gradle腳本有利於整個項目開發語言的統一,不需要另外學習Groovy的語法
- Kotlin DSL 支持跳轉到源碼
- Kotlin DSL 在編譯時檢查錯誤
- Kotlin DSL 支持代碼自動補全和語法高亮
Kotlin DSL的劣勢:
- 編譯速度比Groovy慢
從Groovy遷移到Kotlin DSL
Gradle 版本: 3.5.3
gradle-wrapper版本:5.6.4
新建一個Android項目
我們以一個新的Android項目爲例,一步步從groovy遷移到Kotlin DSL
第一步:修改setting.gradle文件
把setting.gradle
重命名爲 setting.gradle.kts
所有的Kotlin DSL 文件,都是以.kts 爲文件名後綴
然後修改文件裏面的內容:
include (":app")
rootProject.buildFileName = "build.gradle.kts"
這裏做的事情也很簡單,就是把原本的 “:” 改成了 “()” 這也是Kotlin DSL和Groovy語法的差別之一。
第二步:修改Project的build.gradle文件
把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)
}
這裏主要修改的就是三點,我已經在代碼中標識出來了:
- ext改成 val,val是Kotlin不可變變量的關鍵字
- classpath 的 單引號 改爲 雙引號
- task 同樣需要改成 Kotlin 的語法
第三步:修改App的build.gradle文件
同樣的,首先把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")
}
需要注意的地方同樣在註釋中標識出來了:
- apply 需要改成 plugins
- 原本 : 的寫法統統換成 () 或者 =,這是kotlin的setter語法
- 注意buildTypes和fileTree的變化
完成了這幾步之後,我們就可以點擊sync project,如無意外的話應該是可以成功的,到目前爲止其實我們就已經從Groovy成功遷移到了Kotlin DSL了。但是大家有沒有發現一個問題,就是現在我們所有的版本號,依賴版本,TargetSDK等等,都是直接寫在build.gradle.kts文件中的,能不能把這些變量都統一放到一個地方管理呢?特別是多個Module的時候,我們希望只要改動一個地方,所有的依賴都能夠同步。
其實官方已經給我們提供了一個解決方案了,那就是使用buildSrc
第四步:創建buildSrc文件夾
在根目錄下創建一個buildSrc文件夾,也就是和app文件夾同一等級。創建後的結果應該是這樣的:
大家可以先忽略Kotlin文件夾裏面的3個文件。只要創建了src/main/kotlin 以及 build.gradle.kts 文件就可以了。
接下來就要修改build.gradle.kts
文件了:
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
解釋一下,這一個buildSrc文件夾的作用是什麼呢?
官方推薦我們使用這個文件夾來管理整個項目的依賴,也就是說,我們可以在這個路勁定義多個和依賴相關的類。
創建Dependencies.kt文件
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文件截圖,是不是比之前清晰多了呢?