Android 應用程式通常會使用 Gradle 建構系統進行建構。在深入說明如何設定建構作業之前,我們會探索該建構背後的概念,方便您大致瞭解系統。
什麼是建構?
建構系統會將原始碼轉換為可執行的應用程式。建構作業通常會涉及多個工具,用於分析、編譯、連結及封裝應用程式或程式庫。Gradle 會透過工作導向方法來整理及執行這些指令。
工作會封裝指令,將輸入內容轉譯為輸出內容。外掛程式可定義工作及其設定。將外掛程式套用到建構作業會註冊其工作,並使用其輸入和輸出內容將這些工作串連在一起。舉例來說,將 Android Gradle 外掛程式 (AGP) 套用至建構檔案,就會註冊建構 APK 或 Android 程式庫所需的所有工作。java-library
外掛程式可讓您從 Java 原始碼建構 jar。Kotlin 和其他語言都有類似的外掛程式,而其他外掛程式則是用來擴充外掛程式。舉例來說,protobuf
外掛程式的用途是在 AGP 或 java-library
等現有外掛程式中加入 protobuf 支援。
Gradle 偏好採用慣例,而非設定慣例,因此外掛程式可以直接使用預設值,但您也可以透過宣告式網域特定語言 (DSL) 進一步設定建構。DSL 的設計目的是讓您指定要建構的內容,而非建構方式。外掛程式中的邏輯會管理「方法」;您可以在專案 (和子專案) 中的多個建構檔案中指定該設定。
工作輸入內容可以是檔案和目錄,以及編碼為 Java 類型 (整數、字串或自訂類別) 的其他資訊。輸出內容只能是目錄或檔案,因為它們必須寫入磁碟。將工作輸出內容傳輸至另一個工作輸入來源,將工作連結在一起,讓工作必須更早執行。
雖然 Gradle 支援在建構檔案中編寫任意程式碼和工作宣告,但這可能會讓工具更難瞭解您的建構作業,也讓您更難維護。舉例來說,您可以在外掛程式內編寫程式碼的測試,但無法在建構檔案中編寫測試。相反地,您應將建構邏輯和工作宣告限制在外掛程式 (由您或其他人定義),並宣告要在建構檔案中使用該邏輯的方式。
Gradle 建構作業執行時會發生什麼事?
Gradle 建構作業分為三個階段。每個階段都會執行您在建構檔案中定義的不同程式碼部分。
- 初始化會判斷建構作業應納入哪些專案和子專案,並設定包含建構檔案和套用外掛程式的類別路徑。這個階段著重於設定檔,您可以在其中宣告要建構的專案,以及擷取外掛程式和程式庫的位置。
- 設定會註冊每個專案的工作,並執行建構檔案以套用使用者的建構規格。請務必瞭解,設定程式碼無法存取執行期間產生的資料或檔案。
- 「執行」會執行應用程式的實際「建構」。設定的輸出內容是工作的有向非循環圖 (DAG),代表使用者要求的所有必要建構步驟 (在指令列中提供的工作,或在建構檔案中做為預設值)。這張圖表代表工作之間的關係,可能是工作宣告中的明確,或依據工作的輸入和輸出內容。如果工作輸入內容是另一項工作的輸出內容,則必須在該工作之後執行。這個階段會依圖表中定義的順序執行過時的工作,如果工作輸入內容自上次執行後未變更,Gradle 就會略過該工作。
詳情請參閱 Gradle 建構生命週期相關說明。
設定 DSL
Gradle 會使用網域特定語言 (DSL) 來設定建構。這種宣告式方法的重點在於指定資料,而非撰寫逐步 (命令) 指令。您可以使用 Kotlin 或 Groovy 編寫建構檔案,但我們強烈建議您使用 Kotlin。
DSL 會嘗試讓所有人、領域專家和程式設計人員都能更輕鬆地參與專案,定義以更自然的方式呈現資料的小型語言。Gradle 外掛程式可以擴充 DSL,以便設定任務所需的資料。
舉例來說,設定建構的 Android 部分可能會如下所示:
Kotlin
android { namespace = "com.example.app" compileSdk = 34 // ... defaultConfig { applicationId = "com.example.app" minSdk = 34 // ... } }
Groovy
android { namespace 'com.example.myapplication' compileSdk 34 // ... defaultConfig { applicationId "com.example.myapplication" minSdk 24 // ... } }
DSL 程式碼在背景中類似以下程式碼:
fun Project.android(configure: ApplicationExtension.() -> Unit) {
...
}
interface ApplicationExtension {
var compileSdk: Int
var namespace: String?
val defaultConfig: DefaultConfig
fun defaultConfig(configure: DefaultConfig.() -> Unit) {
...
}
}
DSL 中的每個區塊都由一個函式表示,該函式使用 lambda 設定該區塊,以及一個名稱相同的屬性來存取該區塊。這樣可讓建構檔案中的程式碼感覺更像資料規格。
外部依附元件
Maven 建構系統引入了依附元件規格、儲存空間和管理系統。程式庫會儲存在存放區 (伺服器或目錄) 中,中繼資料則包含版本資訊和對其他程式庫的依附元件。您可以指定要搜尋哪些存放區、要使用的依附元件版本,建構系統會在建構期間下載這些項目。
Maven Artifacts 會依群組名稱 (公司、開發人員等)、成果名稱 (程式庫名稱) 和成果版本來辨識。通常以 group:artifact:version
表示。
這種做法可大幅改善版本管理成效。您經常會聽到這類存放區稱為「Maven 存放區」,但這其實與封裝和發布成果的關係。這些存放區和中繼資料已重複使用於多個建構系統,包括 Gradle (以及 Gradle 可發布至這些存放區)。公開存放區可讓所有人共用,且公司存放區會將內部依附元件保留在內部。
您也可以將專案模組化,轉換為子專案 (在 Android Studio 中也稱為「模組」),這些子專案也可以用做依附元件。每個子專案都會產生可供子專案或頂層專案使用的輸出內容 (例如 jar)。透過隔離需要重建的部分,並在應用程式中更獨立處理工作,這樣可以縮短建構時間。
我們會在「新增建構依附元件」中,詳細說明如何指定依附元件。
建構變化版本
建立 Android 應用程式時,您通常會需要建構多個變化版本。變化版本包含不同的程式碼,或使用不同的選項建構,並由建構類型和變種版本組成。
建構類型會變更宣告的建構選項。根據預設,AGP 會設定「發布」和「偵錯」建構類型,但您可以調整這些類型並新增更多類型 (例如用於階段或內部測試)。
偵錯版本不會壓縮或模糊處理您的應用程式,會加快建構速度並依原樣保留所有符號。此版本也會將應用程式標示為「可進行偵錯」、使用一般偵錯金鑰簽署應用程式,以及在裝置上存取已安裝的應用程式檔案。這樣一來,您就能在執行應用程式時,探索檔案和資料庫中的已儲存資料。
發布子版本會最佳化應用程式、使用發布金鑰簽署應用程式,並保護已安裝的應用程式檔案。
您可以使用產品變種版本,變更應用程式的納入來源和依附元件變化版本。舉例來說,您可以為應用程式建立「試用版」和「完整版」變種版本,也可以建立「免費」和「付費」變種版本。您將通用來源寫入「main」來源集目錄中,並在以變種版本命名的來源集中覆寫或新增來源。
AGP 會為每個建構類型和變種版本的組合建立變化版本。如果您未定義變種版本,系統會根據建構類型為變化版本命名。如果您同時定義兩者,變化版本的名稱為 <flavor><Buildtype>
。舉例來說,根據建構類型 release
和 debug
,以及變種版本 demo
和 full
,AGP 會建立變化版本:
demoRelease
demoDebug
fullRelease
fullDebug
後續步驟
現在,您已瞭解建構概念,接下來請查看專案中的 Android 建構結構。