【版權申明】非商業目的註明出處可自由轉載
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/106763989
出自:shusheng007
系列文章:
秒懂Gradle之從完全懵逼到是懂非懂
概述
通過秒懂Gradle之從完全懵逼到是懂非懂 熟悉了gradle,達到了是懂非懂的境地,今天讓我們實戰演練一下,此演練具有實際意義,如果你願意完全可以將其用在實際項目中。
Gradle從5.0就已經支持Kotlin DSL1.0了,說明Gadle從5.0開始已經準備好在生產上使用了,何況現在已經發展到6.5了,時機已經很成熟。
Android Studio 4.0 對應的gradle 插件爲4.0,對應的Gradle爲6.1.1了,所以是時候嘗試一下使用kotlin DSL寫gradle腳本了。
爲什麼要用Kotlin DSL寫gradle腳本
撇開其他方面,就單從提高程序員生產效率方面就有很多優點:
- 腳本代碼自動補全
- 跳轉查看源碼
- 動態顯示註釋
- 支持重構(Refactoring)
- …
怎麼樣,要是你經歷過groovy那令人蛋疼的體驗,kotlin會讓你爽的起飛,接下來讓我們開始吧。
從Groovy到Kotlin
讓我們使用Android Studio 新建一個Android項目,AS默認會爲我們生成3個gradle腳本文件。
- settings.gradle (屬於 project)
- build.gradle (屬於 project)
- build.gradle (屬於 module)
我們的目的就是轉換這3個文件
第一步: 修改groovy語法到嚴格格式
groovy既支持雙引號""
也支持單引號''
,而kotlin只支持雙引號,所以首先將所有的單引號改爲雙引號。
例如 include ':app'
-> include ":app"
groovy方法調用可以不使用()
但是kotlin方法調用必須使用()
,所以將所有方法調用改爲()
方式
例如
implementation "androidx.appcompat:appcompat:1.0.2"
改爲
implementation ("androidx.appcompat:appcompat:1.0.2")
groovy 屬性賦值可以不使用=
,但是kotlin屬性賦值需要使用=
,所以將所有屬性賦值添加=
.
例如
applicationId "com.ss007.gradlewithkotlin"
改爲
applicationId = "com.ss007.gradlewithkotlin"
完成以上幾步,準備工作就完成了。
第二步:修改文件名並轉換
由於gradle支持groovy 與kotlin腳本混編,所以我們沒轉換完一個文件就同步一下,確保沒有錯誤。
-
轉換setting.gradle文件
將文件名加上kts後綴爲
setting.gradle.kts
然後將內容修改爲如下所示(其實完成第一步後就不用做修改了,和groovy一毛一樣,)
include(":app") rootProject.name = "GradleWithKotlinDsl"
-
轉換project的build.gradle文件
將文件名加kts後綴爲
build.gradle.kts
然後將內容修改爲如下所示:
buildscript { var kotlinVersion: String by extra kotlinVersion="1.3.72" repositories { google() jcenter() } dependencies { classpath ("com.android.tools.build:gradle:4.0.0") classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() } } tasks.register<Delete>("clean") { delete(rootProject.buildDir) }
這個文件轉換有兩個地方需要注意:
第一:buildscript{}
裏的ext.kotlin_version'
改爲 var kotlinVersion: String by extra
關於extension object
這塊,kotlin表現的不如groovy優秀,比較囉嗦。
第二:task 的申明方式變了
- 轉換module的build.gradle文件
這個是我們的重點要轉換的了,也最爲複雜。首先將文件名加kts後綴爲build.gradle.kts
。
然後修改內容如下:
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
}
android {
compileSdkVersion (29)
buildToolsVersion ("30.0.0")
defaultConfig {
applicationId = "top.ss007.gradlewithkotlindsl"
minSdkVersion (21)
targetSdkVersion (29)
versionCode= 1
versionName= "1.0"
testInstrumentationRunner="androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
dependencies {
implementation (fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
implementation ("org.jetbrains.kotlin:kotlin-stdlib:1.3.72")
implementation ("androidx.core:core-ktx:1.3.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")
}
有3處需要特殊處理
第一:插件的引入方式從apply plugin
到聲明式
plugins{
id(xxx)
...
}
第二:buildTypes{}
塊裏面獲取buildType
的方式有變化。
因爲buildTypes塊裏面的類型爲NamedDomainObjectCollection<BuildType>
,其不存在名爲release
的方法。而是通過release
這個name可獲取到一個BuildType類型的對象。而這個對象裏面有一個方法叫setMinifyEnabled(false)
,寫成屬性調用方式爲isMinifyEnabled = false
第三:dependencies{}
塊裏面編譯lib 文件夾中jar
文件的內容有變化
dependencies {
implementation (fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}
我們看一下fileTree那個方法的簽名
ConfigurableFileTree fileTree(Map<String, ?> args);
可見其需要一個Map的入參
完成以上幾步後同步一下gradle腳本就ok了。
到目前爲止一切都工作正常,但是在實際項目中我們經常使用project下的gradle腳本的一個extension object來統一維護版本號,如下所示:
ext{
// Android config
androidBuildToolsVersion = "30.0.0"
...
}
但是在kotlin裏面從其他模塊下訪問不到project下的extra,所以需要使用buildSrc的方式
使用buildSrc改進維護性
在根目錄下創建一個buildSrc
目錄,當構建時gradle會自動包括此目錄下的文件,在所有gradle文件中都是可以訪問到這裏面的類,我們可以將版本號統一維護在這裏。
其文件結構如下:
Config 文件內容如下
object Config {
object Android {
const val buildToolsVersion = "30.0.0"
const val minSdkVersion = 21
const val targetSdkVersion = 29
const val compileSdkVersion = 29
const val applicationId = "top.ss007.gradlewithkotlindsl"
const val versionCode = 1
const val versionName = "1.0"
}
object AndroidLib{
const val appcompatVersion= "1.1.0"
const val constraintLayoutVersion="1.1.3"
}
...
}
然後就可以在gradle文件中引用裏面的值了,例如:
defaultConfig {
applicationId = Config.Android.applicationId
minSdkVersion (Config.Android.minSdkVersion)
...
}
dependencies {
...
implementation ("androidx.appcompat:appcompat:${Config.AndroidLib.appcompatVersion}")
implementation ("androidx.constraintlayout:constraintlayout:${Config.AndroidLib.constraintLayoutVersion}")
}
總結
總體來說,gradle團隊已經擁抱Kotlin了,教程也是groovy和kotlin共存的,相信kotlin在gradle的使用中會越來越多的,說不定哪天android studio的模板項目就會使用kotlin作爲默認gradle腳本的,畢竟kotlin已經是Android開發的首推語言了。
不知不覺又快晚上12點了,我也該去睡覺了,腦中突然浮現出一種奇妙的想法:多年年以後回看自己的文章是一種什麼樣的感覺?覺得應該拍點視頻了,多年以後回看自己的視頻感覺比文章要有意思的多吧。
如果要深入瞭解,可以參考官網相關部分 Gradle Kotlin DSL Primer
我覺得是到了點贊收藏的時候了,如果你覺得文章還行,建議關注博主。
本文源碼:GradleWithKotlinDsl