給Android開發者的Gradle入門指南
本文的目的是為您提供關于 Gradle 的高級概述,以及在開發 Android 應用程序時如何適應整個構建系統。 我將通過 Gradle 和 Gradle 的 Android 插件的基礎知識,以及新的 Android 項目附帶的默認 build.gradle 腳本來進行講述。
本文不會教你如何編寫定制的 Gradle 腳本或任何類型的東西。正如標題所說,這是給真正意義上的初學者的文章。
背景故事
我先坦白一下:我主要是一名 iOS 開發人員。在整個職業生涯中,只有四分之一的時間用于開發 Android 應用程序。正因為如此,我從來沒有真正理解 Gradle 是什么。當我點擊 Android Studio 中的綠色播放按鈕時,我知道這是“工作”,但我不知道它實際上做了什么。
當我看到“ Gradle Build Running ”這個詞超過 10 秒時,這讓缺少相關知識的我非常不耐煩。 “有什么需要這么久?”我會問 Android Studio ,希望有某種跡象表明它不僅僅是卡住了。在工作中,每當我看到一個 Android 開發者茫然地盯著屏幕,我經常開玩笑地問他們:“你是在等 Gradle 構建嗎?
最終我感到沮喪,并決定找出要如何減少構建時間。我看了一個名為“ 加快 Android 的 Gradle 構建 ”的 Google I/O ’17 的演講,相信會解開所有我想要的提升 Gradle 速度的關鍵。
40分鐘之后,我意識到我對 Gradle 一無所知,所以我根本沒有機會做得更好。 我停下腳步,決定現在是去理解 Gradle 的時候了。
基礎知識
為了解決這個問題,讓我們先弄清楚一些事情:
- Android Studio 不知道如何將 Java&Kotlin 代碼編譯成 APK 文件。
- Gradle 不知道如何將 Java&Kotlin 代碼編譯成 APK 文件。
是的,你沒看錯。
Gradle 本身并不知道如何編譯 APK 文件,因為 Gradle 實際上是一個 通用的構建工具 。它不限于構建 Android 應用程序。在 Gradle 的 GitHub 倉庫 中,它被描述為:
...構建工具,著重于構建自動化和支持多語言開發。如果您在任何平臺上構建、測試、發布和部署軟件,Gradle 提供了一個靈活的模型,可以支持從編譯和打包代碼到發布的整個開發生命周期。 Gradle 本身實際上并不能做太多。所有有用的功能都來自豐富的插件生態系統。把你添加到 Android 應用程序中的所有第三方庫視為插件。您可以使用這些插件來擴展應用程序的功能,就像 Gradle 使用插件來擴展自己的功能一樣。
有很多與 Gradle 捆綁 在一起的插件,以及更多 可以下載的插件 。但是,如果你閱讀 Gradle 附帶的插件列表,則會發現在該頁面上找不到“Android”。
Android Plugin for Gradle
Android Plugin for Gradle 是一個使 Gradle 能夠將您的代碼編譯成用你的密鑰簽名 APK 文件的插件,甚至將 APK 安裝到你的模擬器或測試設備上。這個插件驅動你的整個構建系統。
沒有它,Gradle 就無法知道如何對代碼做任何事情。這也就是我前面說的 Android Studio 和 Gradle 不知道如何構建你的 Android 項目:這個插件是 Android Studio 和 Gradle 之間的魔法鏈。
深入腳本
現在我們已經掌握了一些基礎知識,接下來看看如何轉化為日常實現。當你在 Android Studio 中啟動一個全新的項目時,會獲得以下文件:
這些文件是什么?
所有帶有“ gradle ”文字的文件都用于為我們的 Android 項目配置 Gradle 。里面存在多個文件,因為它們都有不同的用途。
Gradle Wrapper
gradle-wrapper.properties 文件有一個簡單的目的:決定在構建項目時使用哪個 Gradle 版本。它將隨后會自動為你下載并保存該版本的 Gradle 。如果你在 Mac 上使用,運行下面命令 ls ~/.gradle/wrapper/dists/ 你就可以看到 Gradle Wrapper 曾為你下載過的所有 Gradle 版本。
注意你的 Gradle 版本是獨立于你的 Android 插件版本的。在本文撰稿時,目前 最新的 Gradle 版本是 v4.3 。Android Studio 依然默認使用 v4.1 ,所以如果你愿意,你可以很安全的將版本升級到 v4.3 。
settings.gradle
settings.gradle 文件是保存在你通知 Gradle 的地方,即你的工程所有的子工程 /module 目錄下。這是通過 include 命令完成的。如果你將另一個模塊添加到你的工程中,Android Studio 將會自動將其添加到這個文件中。
build.gradle
從 Gradle 的角度來看,我們的工程被認為是一個 多工程構建, 其中你擁有一個根項目以及一個到多個子工程。從 Android 開發者的角度來看,這些子工程被稱為 module (模塊)。
這就是為什么你會看到兩個 build.gradle 文件的原因。一個是給根項目的,另一個是給伴隨著你的項目的 app 模塊的。讓我們先看看你的根項目的格式吧。
- 這個完整的 buildscript {} 塊用于告知 Gradle 腳本本身,關于編譯本項目需要的那些。
- 我們在這個 buildscript 中聲明了 Android Gradle 插件的依賴性。“3.0.0” 表示要使用的插件版本。
- 我們告知 Gradle 我們需要到 google() Maven 代碼庫和 jcenter() 代碼庫中檢索一些事項。
- 在Gradle 項目中添加 額外的屬性 ,以支持它可以在整個 Gradle 項目中是可訪問的。換言之,這是 Gradle 風格的全局變量。我們可以通過使用決定所導入的 kotlin-gradle-plugin 的版本的方式來查看該變量的值。
- 正如名字所暗示的, allprojects{} 塊被用于通知 Gradle 關于所有需要編譯的子項目,并使用這個代碼庫集合來解決所有需要的依賴項。
- 首先,我們應用真實的 Android 插件,然后我們使用 其擴展插件 來應用 Kotlin Android 插件。
- 此完整的 android{} 塊工作的唯一原因是因為我們要求 Gradle 使用之前提到的 Android 插件。我深信你對修改該模塊內部的值非常熟悉,但你是否對所有可能放入該塊的值有過好奇呢?好事情是它 在此都被文檔化了!
- 這里就是你添加 Gradle 所依賴的第三方庫的位置。注意在你的 app 的 build.gradle 中并沒有 repositories{} 塊。既然我們已經在根項目的 allprojects{} 塊中聲明了,這里就沒有必要了。
- 還記得我們在根構建文件中的全局變量嗎?是的,這里就是起作用的地方。最好采用類似 管理你所支持庫的版本 一樣的策略可能是個不錯的主義,這可以保證他們都是用同一個版本。
Gradle 任務
現在我們透過腳本,還有一件你必須知道的關于 Gradle 的事:任務。
任務是基本的東西,Gradle 可以每當被觸發時生成,記得早前(上文)我說 Android Studio 其實不知道如何編譯你的代碼?因為在 Android Studio 點擊大綠色的 play 按鈕會觸發一個具體的任務在 Gradle 執行。
在右下角,點擊 “Gradle Console” 按鈕去打開 Gradle Console ,然后點擊 play 按鈕運行 app ,一大堆命令會出現,但我們只關心頂部的:
- Executing tasks: [:app:assembleDebug]
我們只討論 Gradle 執行的 assembleDebug 任務,我們可以通過命令行來做相同的事,點擊左邊的 Terminal 按鈕并運行本段代碼:./gradlew assembleDebug --console plain
瞧!你只是讓 Gradle 運行與播放按鈕完全相同的命令。有幾件事要注意:
- ./gradlew 意味著使用 Gradle Wrapper 來代替 “vanilla” Gradle 。強烈建議您始終使用 Wrapper 版本。
- assembleDebug 是你剛剛要求它運行的任務的名稱。
- --console plain 告訴 Gradle 打印生成日志,就像你在 Android Studio 中看到的一樣。完全是可選的。
讓我們運行最后一個命令:./gradlew tasks
這個命令將列出 Gradle 目前在這個項目中所知道的所有任務,并提供每個任務的簡短描述。很酷吧?
現在,點擊 Android Studio 右上角的 Gradle 標簽。
哈哈!這是一樣的東西。這一部分只是列出了 Gradle 可以為這個項目運行的所有可能的任務。在這里雙擊 assembleDebug ,就可以做到與剛剛在命令行上做的一樣的事情,并且和播放按鈕做同樣的事情。
如果您在 Android Studio 中運行“重建項目”命令,同時保持 Gradle 終端處于打開狀態,你將會意識到它所做的只是運行 clean 任務,然后運行 assembleDebug 命令。這就是我發現在重建項目之前運行清理項目是完全不必要的,因為重建項目無論如何都會運行相同的 clean 任務。
結束時的思考
我希望這篇文章能夠讓你更好地了解 Gradle 如何適應你的開發流程。為按照你們常規的思考方式來寫,這花費了我更長的時間,但是這對我來說是非常值得的。我已經重新看了“ 加速 Android Gradle 構建 ”的視頻,我很自豪地說,在看完后我不會再完全迷失了。