Gradle Kotlin DSL , 你知道它嗎?

ldzsl發表於2021-09-09

圖片描述

一.前言

kotlin我相信大家實際上還是挺熟悉的,哪怕不熟悉,也沒有關係,它跟Java是百分百相容的,很多的語法是有點類似的,所以只要有Java基礎,學習Kotlin並不是什麼難事,再加上現在kotlin大熱,Google多次在各種大會上力推,如果這個時候我們掌握了kotlin,肯定能給我們提升很大的幫助。

而且Kotlin本身就是一門讓人愛不釋手的語言,寫起來還是很讚的,不管你需不需要學習,進來看看,開闊下視野總是沒錯的。

自Kotlin被Google轉正之後,這門語言就備受我們Android開發者的關注,經過幾年的發展下來,Kotlin儼然已經成為了一門出色的開發語言,它人性化的語法以及語法糖都深受人們的喜愛,再加上這幾年來AI概念的大熱,讓越來越多的開發者正襟危坐,如何提高自身的競爭力?如何提高自身的技術棧?這成了大部分初中級開發者的第一個難關,而在另一大領域物聯網行業中風生水起的語音控制,也逐漸開始嶄露頭角,如百度小度,小米小愛,天貓精靈等,那麼如果Kotlin + AI + 語音控制,會碰撞出什麼火花來呢?

在我的新課程中,就使用到了此技術,並且輔以元件化的架構,有興趣可以瞭解一下

連結直達:

二.Gradle Kotlin DSL入門

總所周知,我們現在Android Studio是使用Gradle來編譯,而預設的構建語言是Groovy,但是Gradle實際上是支援Kotlin來編寫Gradle構建指令碼的,常見的構建指令碼是.gradle結尾,而Koltin語法編寫的指令碼則是.gradle.kts,今天就帶大家來嘗試一下,而Gradle官網也是給出了Groovy遷移Kotlin的指導文章,有興趣也可以看下

連結直達:

圖片描述

Gradle的Kotlin DSL提供了傳統Groovy DSL的替代語法,並在受支援的IDE中提供了增強的編輯體驗,並具有出色的內容輔助,重構,文件等功能,這是官方給出的一些定義,當然,他也是有限制的,所以儘可能的保證Gradle和Android版本為最新版本是很有必要的,當然,JDK的版本至少是在8或者以上,有了這些鋪墊之後,我們就可以開始著手來改造一個專案了

三.Gradle指令碼改造

我們先區分一些語法的不同

  • 1.Groovy字串可以用單引號’string’或雙引號引起來"string",而Kotlin需要雙引號"string"。
  • 2.Groovy允許在呼叫函式時省略括號,而Kotlin始終需要括號。
  • 3.Gradle Groovy DSL允許=在分配屬性時省略賦值運算子,而Kotlin始終需要賦值運算子。

然後我們要知道,一個基於Gradle構建的專案,預設會有哪些配置檔案?

  • settings.gradle
  • project/build.gradle
  • app/build.gradle

無外乎這三個配置,那麼我們現在就開始來改造吧。

1.settings.gradle

在我們專案的根目錄下,有一個settings.gradle這樣的檔案,它主要是負責我們專案的Model宣告,那麼我們首先先重名名一下檔名,增加.kts的字尾,如圖,連圖示都變了

圖片描述

那麼我們內部的程式碼應該如何重寫?先來看下原先的程式碼

include ':app'
rootProject.name = "KotlinDSL"

這段程式碼很簡單,就是宣告瞭app這個主Module,同時定義了我們project的名稱,我們可以透過kotlin的語法進行改寫:

圖片描述

為了便於閱讀,這裡我直接截圖顯示,可以看到這裡我們遵循了剛才的注意事項,把app的單引號變成了雙引號,然後等於號修改成了括號,來看下原始碼

圖片描述

再來看下Groovy中的原始碼:

圖片描述

你會發現,其實語法差不多,但是要注意我們剛才上面的提示資訊:

Gradle Groovy DSL允許=在分配屬性時省略賦值運算子,而Kotlin始終需要賦值運算子。

有了這一層的說明,大家就明白什麼意思了,那麼懂了這些基本知識之後,我們就可以來晚一些大的了。

2.project/build.gradle

那麼我們應該如何來處理呢?我們先把它的字尾改了

圖片描述

改完了之後,我們就要來看裡邊的程式碼了

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.3.72"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.0"
        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()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

改造第一步,就是我們的classpath了,那麼在Groovy中,我們有一個ext的擴充套件,但是在kt中實際上是沒有的,所以我們只能自己先宣告一個區域性變數了,另外就是classpath引入的全域性依賴,我們還是要用大括號括起來,其他倒是不需要改變,但是可以看到,還有一個clean的任務,這個也是需要重寫的,我們可以看到它是利用Delete中的delete函式來刪除我們的build資料夾,這就好辦了,直接改下即可,來看下截圖

圖片描述

IDE還是非常的友好的,一些基本的提示都是有的

當兒,我們也可以簡化依賴的操作,就拿kotlin外掛來說吧,它最長了,我們可以宣告一下

圖片描述

可以看到,classpath是支援kotlin函式的,我們只要傳入module的名稱和版本號即可,所以這樣寫是不是非常的美觀呢?

圖片描述

當然,這些都是小兒科,我們再來改造下內容比較多的app下build.gradle

3.app/build.gradle

先把字尾改了,這都是老生常談了,至此我們的工程配置到了最後一步了,但是我們要走的路還很遠

圖片描述

這裡面的內容很多,我就不貼程式碼了,而是分模組給大家理清楚邏輯,先把最基本的單引號改成雙引號,接著把等號的函式呼叫全部改成括號,然後接著往下看

外掛的引入

Groovy的外掛引入是這樣的

apply plugin : 'com.android.application'
apply plugin : 'kotlin-android'
apply plugin : 'kotlin-android-extensions'

我們可以簡化成這樣

圖片描述

SDK引入

而SDK的引入如下

compileSdkVersion 29
buildToolsVersion "29.0.3"

我們可以改成這樣
圖片描述

預設配置

預設配置是這樣

defaultConfig {
    applicationId "com.liuguilin.kotlindsl"
    minSdkVersion 21
    targetSdkVersion 29
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

我們可以改成這樣

圖片描述

這裡要注意的是,像minSdkVersion,targetSdkVersion這種實際上是一個函式,我們來看原始碼

圖片描述

所以我們要加括號,因為Groovy是省略了括號的,而像versionCode,versionName這些,實際上是變數,我們我們用等於號賦值

圖片描述

如果不明白這些引數和函式的意義,不妨大膽的閱讀原始碼。

編譯型別

編譯型別是這樣的

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

我們可以改成這樣
圖片描述

可以看到我們透過getByName來獲取編譯型別,並且可以獲取debug的編譯型別或者自定義的編譯型別

依賴的新增

依賴這塊可以看到Govvey是這樣的

dependencies {
    implementation fileTree (dir: "libs", include: ["*.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'
}

可以看到其他都沒什麼,就是這個fileTree我們要考慮下,在kotlin中使用冒號:來做鍵值對的,那就是map了,所以我們可以這樣改造
圖片描述

至此呢,我們的基本改造算是完成了,能正常執行就表示一切正常了。

在我的新課中,我們從架構上開始入手,從零開始搭建一套以元件化為基礎的應用框架,以Kotlin Gradle DSL為編譯鏈指令碼,AI語音為核心功能,從架構層次到應用層級再到具體功能落實,以清晰優雅的方式完成實戰,提高自己的超前邏輯,向更高階別的工程師鋪墊。

連結直達:

四.Gradle Kotlin DSL進階

我們雖然是改造了指令碼,但是該有的特性還是不能丟的,我們來開始完善

1.自動打包

使用Gradle自動打包,包括渠道等,都是太正常不過了,我們來改造下,先常規的生成一個簽名吧:

圖片描述

我把簽名放在main資料夾下的jks資料夾下

先來看下原生的自動打包是如何做的,首先定義簽名配置

//簽名配置
signingConfigs {
    release {
        //別名
        keyAlias 'kotlin'
        //別名密碼
        keyPassword '123456'
        //路徑
        storeFile file('../app/src/main/jks/kotlin.jks')
        //密碼
        storePassword '123456'
    }
}

然後在編譯型別中,release型別裡引用即可

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        //自動簽名
        signingConfig signingConfigs.release
    }
}

那麼我們現在用kotlin來改寫吧:

圖片描述

差別不算太大,定義好籤名配置之後,去引用下即可

圖片描述

這樣我們就可以使用Gradle的命令打包了

圖片描述

打包成功之後就可以在app/build/output目錄下找到對應編譯型別的包了

圖片描述

當然,這個名字太難看了,我們每次發版本的時候還要自己去修改,那麼我們來修改下名稱

2.輸出檔名稱

Groovy的程式碼如下:

android.applicationVariants.all { variant ->
    def buildType = variant.buildType.name
    def createTime = new Date().format("YYYY_MM_dd_HH_mm", TimeZone.getTimeZone("GMT+08:00"))
    def fileName
    variant.outputs.each {
        if (buildType == "release") {
            fileName = "DSL_V${defaultConfig.versionName}_${createTime}_${buildType}.apk"
        } else if (buildType == "debug") {
            fileName = "DSL_V${defaultConfig.versionName}_${buildType}.apk"
        }
        it.outputFileName = fileName
    }
}

那麼我們最佳化下之後:

圖片描述

最終我們在output資料夾下就可以看到我們命名的應用了

圖片描述

至於時間的話,這個要在後面講

3.指定JDK

我們如果想要使用Lambda表示式的話,需要指定JDK為8或者以上,而Groovy的程式碼如下:

//JDK8
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

那麼在Kotlin中其實就是改成等號賦值即可

圖片描述

4.資源重定向

這個算是黑科技了,有沒有發現我們的res/layout下,當專案龐大的時候,會出現很多的檔案,這是不可避免的,但是我們可以用資源重定向的方式來給佈局檔案進行分類,效果如圖

圖片描述

這樣做的好處呢,首先是不會影響我們正常的使用,其次可以分類好我們的佈局檔案,那這樣的效果需要怎麼實現呢?

先來看下Groovy語言的實現

//資源重定向
def listSubFile = {
    //新資源目錄
    def resFolder = 'src/main/res/layouts'
    //新資源目錄下的資料夾
    def files = file(resFolder).listFiles()
    def folders = []
    //遍歷路徑
    files.each {
        item -> folders.add(item.absolutePath)
    }
    //資源整合
    folders.add(file(resFolder).parentFile.absolutePath)
    return folders
}

sourceSets {
    main {
        //重定向資源
        res.srcDirs = listSubFile()
    }
}

可以看到,定義了一個變數listSubFile去計算迴圈採集我們定義好的layouts,然後得到目錄,再透過sourceSets重新定義資原始檔即可。

如果我們用Kotlin DSL應該如何去寫呢?

圖片描述

很簡單,基本一致,定義一個方法返回list即可。

五.ext擴充套件函式的替代方式

我們在使用Groovy語言構建的時候,往往會抽取一個build_config.gradle來作為全域性的變數控制,而ext擴充套件函式則是必須要使用到的,而在我們的Gradle Kotlin DSL中,如果想要使用全域性控制,則需要buildSrc

連結直達:

複雜的構建邏輯通常很適合作為自定義任務或二進位制外掛進行封裝。自定義任務和外掛實現不應存在於構建指令碼中。buildSrc則不需要在多個獨立專案之間共享程式碼,就可以非常方便地使用該程式碼了。

buildSrc被視為構建目錄。編譯器發現目錄後,Gradle會自動編譯並測試此程式碼,並將其放入構建指令碼的類路徑中。

對於多專案構建,只能有一個buildSrc目錄,該目錄必須位於根專案目錄中。

那麼我們來開始寫吧。

首先建立一個buildSrc的資料夾,然後建立一系列目錄,如圖

圖片描述

其中test目錄是可以不用建立的,建立好之後使用Gradle Sync下,然後就可以看到如下目錄

圖片描述

這裡要注意的是,src目錄要按照我截圖的方式來建立,然後來編輯settings.gradle.kts

rootProject.buildFileName = "build.gradle.kts"

這裡我就指定了一下編譯檔案是build.gradle.kts,再來編輯下這個檔案

圖片描述

按照官方文件的引導,我們寫完編譯指令碼後就可以執行gradle init來編譯了,編譯成功之後我們就可以快樂的玩耍了

1.輸入APK增加編譯時間

在上文中我們有講到如果修改輸出的APK名稱,但是我們每次編譯出來最好增加個時間好做版本管理和歷史版本歸檔,那麼我們可以在APK名稱上增加事件了,而在Groovy語言中可以直接使用java的程式碼獲取到時間,而在我們的DSL中,我們可以在剛才的buildSrc中定義方法

圖片描述

我定義了一個獲取時間的方法後,在build.gradle.kts中可以這樣去修改

圖片描述

然後執行編譯命令

圖片描述

最終我們可以看到,release版本增加了時間,是不是很nice,我們可以繼續去抽取和封裝

2.版本和依賴管理

我把所有的依賴都抽取了出來,可以看下截圖

圖片描述

版本,外掛,SDK版本以及依賴都可以在這個目錄進行更新,方便管理,那麼外部的呼叫情況如何呢?

先來看下project中的build.gradle.kts

圖片描述

這樣呼叫即可,再來看下app的build.gradle.kts

這是配置

圖片描述

這是依賴

圖片描述

至此,你就完全學會了Gradle Kotlin DSL的技巧了。

掌握元件化架構及AI語音的基本組成和使用,多個應用場景提高技術棧,更加深刻的理解Kotlin語言,那就來這裡吧。

課程整體分為四大部分,第一部分著重講解了Kotlin Gradle DSL的指令碼編寫,第二部分著重講解了元件化架構專案的實施,第三部分著重講解了AI人工智慧語音的實現,第四部分則完善語義的場景,讓互動更加人性化。

連結直達:

六.原始碼下載

連結:

提取碼:kxwj

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2325/viewspace-2825891/,如需轉載,請註明出處,否則將追究法律責任。

相關文章