用Kotlin寫Android Gradle腳本

文 | 歐陽鋒

Android應用開發中,離不開Gradle腳本的構建。大部分Android開發同窗忽視了腳本的力量,甚至有很大一部分同窗不知道Gradle腳本是什麼,用什麼語言編寫的;固然,也有至關一部分同窗知道Gradle腳本是使用Groovy語言編寫的,但對於Groovy語言卻一竅不通,只是勉強能夠看懂Gradle腳本。正所謂,知其然,但並不知其因此然...html

換個角度看問題,熟練掌握Gradle腳本還須要精通Groovy語言,這對Android開發同窗來講的確是一個不小的挑戰。這種Java + Groovy的開發套餐對於普通的Android開發者來講的確存在必定的知識斷層,顯而易見的是,部分同窗寫的Gradle腳本簡直「不堪入目」。時間回到去年5月份,Google IO大會上宣佈了一個重磅消息,Android官方開始支持使用Kotlin語言進行應用開發。其實,在這個時間節點上,我已經在生產環境使用Kotlin開發Android將近一年。對於我來講,這無疑是一個讓人欣喜若狂的消息。但,驚喜還遠遠不止這些,過了一段時間,我又看到了這篇文章 Kotlin Meets Gradle。頗有詩意的標題:當Gradle邂逅Kotlin,文章的核心意思是:Gradle團隊正在嘗試使用Kotlin語言做爲Gradle腳本的官方開發語言。android

我想,也許,Android開發者的春天就要到了!git

Why use Kotlin ?

在寫Gradle腳本的時候,最痛苦的莫過於沒有任何提示,惟一的調試手段就是使用print方法打印調試日誌。正如 Kotlin Meets Gradle 文中所說,當你使用Kotlin語言編寫Gradle腳本的時候,你會發現一切都變得有趣起來。忽然:github

  • 腳本代碼能夠自動補全了
  • 源碼之間能夠互相跳轉了
  • 插件源碼更容易看懂了
  • 重構(Refactoring)也能夠支持了 ...

固然,驚喜還不止這些,當你開始決定使用Kotlin語言的時候,彷彿一切都變得美好了起來!編程

Let's start

好了,廢話很少說,接下來咱們開始嘗試用Kotlin語言編寫Gradle腳本。因爲當前 kotlin-dsl 正處於預發佈狀態(kotlin-dsl的最新版本是0.14.2,對應Gradle插件版本4.5),IDE的支持也不完善,爲了更好的體驗該功能,推薦你們使用以下配置:bash

實驗室配置

操做系統: macOS 10.13.2閉包

Android Studio: 3.1 Canary 9app

Gradle Wrapper: 4.5ide

Gradle Plugin: 3.1.0-alpha9學習

Kotlin:1.2.21

操做步驟

首先,按照以往步驟建立一個Android工程:

接下來,改造開始,Gradle Script Kotlin腳本以.gradle.kts後綴結尾。所以,咱們先將工程根目錄settings.gradle改名爲settings.gradle.kts

這個地方的錯誤有兩個緣由:

  • Kotlin語言中,單引號只能包裹字符,不能包裹字符串
  • Kotlin語言中,方法調用使用括號。僅在使用infix修飾的方法中能夠省略括號。這裏顯然是一個正常調用方法。所以,咱們修改成:
include("app")
複製代碼

接下來,修改根目錄的build.gradle腳本,用一樣的方式修改後綴,方法修改成括號調用,修改後的內容以下:

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        // 這裏修改成括號調用便可
        classpath("com.android.tools.build:gradle:3.0.1")
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}
複製代碼

注意:在修改後綴名稱的時候IDE會出現警告提示,這裏能夠忽略,選擇continue便可。

因爲咱們手動修改了build.gradle腳本,爲了保證工程可使用這個腳本,須要在settings.gradle.kts中添加一行代碼,讓Gradle知道使用build.gradle.kts腳本構建。所以,最後的settings.gradle.kts代碼以下:

include("app")
rootProject.buildFileName = "build.gradle.kts"
複製代碼

最後一步,修改app模塊build.gradle文件,這也是最複雜的一步,修改完後綴名後,你會看到整個腳本所有被紅色標識錯誤:

別慌!仍是同樣的方式,這裏咱們先將這裏的全部代碼註釋掉。在最上方逐一對應修改,apply plugin部分修改成:

plugins {
    id("com.android.application")
}
複製代碼

接下來,修改android {}閉包部分。這裏有兩個小技巧,因爲目前IDE的支持不是很完善,在輸入的時候稍微等待一段時間,IDE會給出相應的提示。另外,若是沒有提示,例如android {}閉包就沒有任何提示,輸入完成後展開右側gradle面板,選擇gradle/buid setup/init,雙擊執行:

在底部面板能夠看到任務執行是否成功。注意,即便任務執行成功,腳本依然可能被紅色標識,這是IDE支持不完善致使的,能夠忽略。

修改完成後的內容以下:

android {
    compileSdkVersion(27)
    buildToolsVersion("27.0.2")

    defaultConfig {
        applicationId = "com.youngfeng.kotlindsl"
        minSdkVersion(15)
        targetSdkVersion(27)
        versionCode = 1
        versionName = "1.0"
        testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }
    }
}
複製代碼

注意:你在使用的過程當中,依然可能會遇到不管如何都不生效的問題。這個時候彆着急,使用./gradlew assembleDebug命令調試,查看終端找到錯誤緣由。Windows用戶去掉./執行便可。

最後的依賴部分,一樣地,所有修改成括號調用便可。這裏就不贅述了,文章的最後部分會提供操做視頻,在使用過程當中有任何問題能夠打開操做視頻參考,若是依然不能解決,能夠在文章下方給我留言,我會在第一時間給你答覆。修改後的內容以下:

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
    implementation("com.android.support:appcompat-v7:26.1.0")
    implementation("com.android.support.constraint:constraint-layout:1.0.2")
    testImplementation("junit:junit:4.12")
    androidTestImplementation("com.android.support.test:runner:1.0.1")
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.1")
}
複製代碼

經過上面的步驟,從Groovy轉換到Kotlin的步驟已經所有完成,你能夠在終端輸入./gradlew assembleDebug測試是否能夠正常構建了:

統一依賴管理

上面的步驟雖然完成了腳本的轉換,但依賴的管理依然是混亂的,爲了實現相似 Snake 工程的統一依賴管理,咱們還須要作一些工做。

Gradle官方提供了使用 buildSrc 目錄實現自定義任務和插件邏輯,這裏咱們可使用它完成依賴的統一處理,一個完整的buildSrc目錄結構以下:

Deps類中,能夠這樣定義依賴結構:

object deps {
    object plugin {
        val gradle = "com.android.tools.build:gradle:3.1.0-alpha09"
        val kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.21"
    }

    object kotlin {
        val stdlibJre7 = "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.21"
    }

    object android {
        object support {
            val compat = "com.android.support:appcompat-v7:27.0.2"
            val constraintLayout = "com.android.support.constraint:constraint-layout:1.0.2"
        }

        object test {
            val junit = "junit:junit:4.12"
            val runner = "com.android.support.test:runner:1.0.1"
            val espressoCore = "com.android.support.test.espresso:espresso-core:3.0.1"
        }
    }
}
複製代碼

定義以後,咱們就能夠在腳本中直接引用了:

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
    implementation(deps.kotlin.stdlibJre7)
    implementation(deps.android.support.compat)
    implementation(deps.android.support.constraintLayout)
    testImplementation(deps.android.test.junit)
    androidTestImplementation(deps.android.test.runner)
    androidTestImplementation(deps.android.test.espressoCore)
}
複製代碼

是否是漂亮了許多?

至此,整個轉換過程就順利完成了,爲了保證轉換的成功率,我推薦使用文章開頭的實驗室配置。若是版本太低,不保證能夠轉換成功。最新版本的kotlin-dsl會跟隨最新版本的Gradle插件發佈,所以必定要使用最新版本。另外,目前IDE對kts的支持依然不完善,即便正確的寫法也會報錯,這個必定要注意,不要被IDE欺騙了。

更詳細的操做,請看視頻教程

騰訊視頻:用Kotlin寫Android Gradle腳本

一些建議

雖然使用Kotlin語言寫腳本是一件很是美妙的事情,但目前依然存在一些問題:

  • IDE支持不完善
  • kotlin-dsl 正在快速開發中,語法變更較大
  • 缺乏官方文檔
  • 互聯網上缺乏相關資料,遇到問題很難追蹤

所以,目前我並不推薦你在生產環境中使用,但能夠做爲平常學習練手之用。預計1.0版本的發佈在今年6月份左右,正式版本發佈後,我推薦你當即將Gradle腳本轉換到Kotlin語言。

遇到問題,看這裏 ==>

在使用的過程當中,按照文章一樣的步驟,你依然可能會遇到不少問題。所以,我爲你整理了目前互聯網上能夠參考的資料,你能夠收藏這篇文章。遇到問題別慌,來這裏查找答案。

關於kotlin-dsl的開發路線圖,請看這篇文章:blog.gradle.org/kotlin-scri…

若是你在使用過程當中,遇到了任何問題,而且肯定是 kotlin-dsl 的bug,請點這裏:github.com/gradle/kotl… 並推送 issue

若是你遇到了知識盲點,而且在Google找不到答案。能夠來 Slack#gradle頻道反饋,我在 Slack 的暱稱是Scott Smith,也歡迎你給我發送私信消息。

本篇文章例子完整代碼,請點擊這裏:github.com/yuanhoujun/…

kts文檔正在編寫當中,具體進度,請點這裏:github.com/gradle/kotl…

歡迎加入Kotlin交流羣

若是你也喜歡Kotlin語言,歡迎加入個人Kotlin交流羣: 329673958 ,一塊兒來參與Kotlin語言的推廣工做。

學更多編程知識,掃描下方二維碼關注歐陽鋒工做室

歐陽鋒工做室

得到更好閱讀體驗,請閱讀原文:www.jianshu.com/p/8fdfbcf35…

相關文章
相關標籤/搜索