開發人員關係工程師
隨著 Android 應用程式規模擴大,AI 程式碼輔助工具也成為不可或缺的一環,使用可執行的程式碼設定建構作業,可能會導致同步時間變慢、邏輯不穩定,以及複雜度增加,進而造成瓶頸。
Lightbuild 是 Google 的宣告式、設定導向建構引擎介面,專為現代 Android 開發作業設計。
本課程將探討 Lightbuild 管理建構作業的新方法,以及如何使用 Lightbuild 建構示範應用程式。瞭解如何將建構設定與執行作業分離,在 Android Studio 中以極快的速度同步,加快專案開啟速度,同時提供可預測的結構定義,讓 AI 編輯更安全可靠。我們也會介紹 Lightbuild 的代理友善 CLI 工具,可用於在本機電腦、團隊和 CI/CD 管道中建立可重現的建構作業
resolved.deps 檔案,藉此略過指令碼評估。這些檔案也可以在 CI/CD 建構期間做為鎖定檔案。query 和 resolve 等指令,可輸出 JSON 格式的代理工作流程。Lightbuild 目前可在 Android Studio Canary 中試用。轉錄稿
大家好。
我是 Juan Sebastian Oviedo。
我是 Android 開發人員體驗團隊的產品經理。
今天我和 Scott 要向大家介紹 Lightbuild,這項實驗性功能可提供全新的 Android 應用程式建構體驗。
我會說明這項專案的背景、背後的理念,以及我們認為現在是重新思考 Android 專案設定方式的適當時機。
此外,我也會說明這種新方法如何為 Android 應用程式開發的未來奠定基礎。
首先,我們來瞭解目前的運作方式。
Gradle 和命令式建構指令碼可讓開發人員以程式輔助方式,定義建構作業的幾乎所有內容。
舉例來說,您可以採用根據 Git 記錄動態計算版本代碼的邏輯,或定義轉換資產的自訂工作。
// build.gradle.kts
android {
compileSdk = 37
buildTypes {
debug {
// Custom logic in build script
val commit = providers.exec {
commandLine("git", "rev-parse",
"--short", "HEAD")
}.standardOutput.asText.get()
.trim()
versionNameSuffix = "-$commit"
}
}
}除了 Gradle 之外,還有 AGP (Android Gradle 外掛程式),可將 Gradle 的通用引擎調整為 Android 工具鍊。
Gradle 和 AGP 共同構成動態系統,為現今數百萬個正式版應用程式提供建構設定體驗。
由於這種彈性,我們的開發人員工具會在特定的架構生命週期內運作。
開啟專案、切換分支版本或編輯建構檔案時,IDE 必須清楚瞭解專案設定,才能提供程式碼自動完成和程式碼導覽等功能。
由於建構檔案是以命令式、圖靈完備語言編寫,因此 IDE 瞭解設定的唯一一般方式就是執行建構指令碼。
在 IDE 同步期間,建構系統會進入設定階段。
它會評估建構指令碼、執行外掛程式邏輯,並建構專案模型。
這樣一來,Android Studio 的專案檢視畫面就會與實際專案設定一致。
身為開發人員,您最重視的是提供優質的 Android 應用程式,並將其提供給使用者。
不過,管理建構指令碼、將 AGP 保持在最新狀態,以及讓專案與 IDE 保持同步,都需要花費時間和精力。
Google 和更廣泛的生態系統中,有多項計畫致力於改善這個領域的開發人員體驗。
Declarative Gradle 和 Kotlin 工具鍊等計畫,旨在以宣告式建構設定取代可執行的建構指令碼。
Android Studio 內建 AGP 升級助理,可引導您完成從某個 AGP 版本升級至另一個版本所需的變更。
我們也提供升級技能,代理程式可以安裝並按照指示升級 AGP。
此外,我們也投入資源開發分階段同步和彈性同步等功能,讓開發人員在同步及匯入專案時享有更優質的體驗。
每項措施都針對一個環節,讓開發人員能花更多時間建立應用程式,減少建構專案、管理建構檔案和同步處理專案的時間。
除了這項工作,我們也思考了更廣泛的問題。
如果我們從頭開始重新構思專案設定方式,會怎麼樣?
從現今 Android 應用程式的架構方式來看,我們發現應用程式已大幅轉向高度模組化。
大型程式碼集通常有數十個甚至數百個模組,包括 UI 模組、功能模組、網域模組和資料模組。
雖然根應用程式有時可能需要自訂封裝,但絕大多數程式庫模組都遵循標準化的可重複模式。
建構檔案中其實不需要有任意可執行的程式碼。
只要有明確的方式,就能說明結構和依附元件。
這項觀察結果促使我們開發 Lightbuild。
Lightbuild 仰賴兩大支柱。
首先,它使用宣告式語法進行設定,可清楚區分建構設定和邏輯。
第二,透過預先解析依附元件,提供快速的 IDE 同步體驗。
我會詳細說明各個關鍵面向,讓您瞭解這些面向對日常工作流程的影響。
首先介紹宣告式建構設定。
查看畫面左側的檔案。
這代表目前的模組設定。
// build.gradle.kts
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.compose)
}
val gitCommit = providers.exec {
commandLine("git", "rev-parse", "--short", "HEAD")
}.standardOutput.asText.get().trim()
android {
namespace = "com.example.app"
compileSdk = 37
defaultConfig {
minSdk = 24
buildConfigField("String", "GIT_COMMIT",
"\"$gitCommit\"")
}
buildFeatures {
compose = true
buildConfig = true
}
}
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics)
...由於這個檔案是可執行的程式碼,因此可以包含區域變數定義、呼叫自訂輔助函式或慣例外掛程式、條件陳述式和內嵌工作定義。
為了讓 IDE 知道這項設定的解析結果,實際上需要執行指令碼。
現在,請查看畫面右側的檔案。
這是類似模組的 Lightbuild 設定。
# lightbuild.yaml
group: "com.example"
version: "1.0.0"
platform: android
type: library
android:
namespace: "com.example.app"
compileSdk:
version:
release:
apiLevel: 37
minSdk:
version:
release:
apiLevel: 24
dependencies:
maven:
- androidx.core:core-ktx:1.10.1
- androidx.lifecycle:lifecycle-runtime-ktx:2.6.1
- androidx.activity:activity-compose:1.8.0這個檔案純粹是宣告式資料。
沒有區域變數定義、自訂輔助函式呼叫、條件陳述式或內嵌工作定義。
清楚說明模組類型、SDK 目標和依附元件。
如果有新工程師加入團隊並開啟這個檔案,他們不需要解讀自訂建構慣用語,因為每個 Lightbuild 專案中的每個 Lightbuild 模組都使用相同的易讀語言。
將設定與邏輯分開,不僅能提升人類可讀性,更能大幅改善 Agent Assist 工作流程。
開發人員將代理納入工作流程後,這些代理必須能讀取及修改建構設定。
不過,除了實際建構專案外,他們無法預測設定變更的副作用。
在設定檔中新增一行,可能會與專案中其他位置動態計算的變數或慣例外掛程式發生衝突。
在 Lightbuild 中,專案設定是確定性的靜態資料圖。
這表示代理程式可以檢查該圖表、瞭解模組拓撲,並使用已知結構定義進行修改。
代理程式只要讀取及寫入結構化資料,就能查看模組清單、依附元件清單及其版本、更新依附元件,甚至新增全新的功能模組。
讓專案設定成為代理輔助工作流程的首要考量。
此外,Lightbuild 並非建構系統的外掛程式,而是建構引擎的介面。
今天發布的 Lightbuild 預先發布版,底層使用 Gradle 做為執行引擎。
不過,我們在 Lightbuild 中採用的架構方法,可讓 Android Studio (IDE) 將專案視為 Lightbuild 專案。
接著來談談第二個要素,也就是開發人員的工作效率和流程:快速 IDE 同步。
即使開發人員將代理納入工作流程,Android Studio 仍是互動式工作不可或缺的工具,例如查看 Compose UI 預覽畫面、在偵錯工具中逐步執行程式碼來調查問題,或使用分析器分析效能。
由於專案設定是確定性的靜態資料圖,IDE 不需要經過指令碼評估階段,也不需要執行外掛程式程式碼,就能瞭解專案。
無論是開啟專案、編輯建構檔案或切換分支,IDE 都能快速處理資訊,讓您立即使用工具。
Lightbuild 之所以能達到這種速度和可靠性,原因之一在於處理依附元件的方式。
一般來說,當您宣告依附元件時,建構系統必須透過遞移依附元件樹狀結構,收集版本資訊並解決衝突。
在 Lightbuild 中,每當依附元件變更時,工具會自動計算傳遞依附元件資訊,並寫入每個模組目錄中的 resolved.deps 檔案。
這樣一來,日後再次開啟專案或重新建構專案時,IDE 和建構工具都不需要重新計算該傳遞依附元件資訊。
建議您將這些檔案簽入原始碼控制系統,這樣一來,當您將變更傳送給團隊成員審查時,他們可以查看傳遞依附元件資訊是否有任何變更,而且他們的機器不需要重新計算該傳遞依附元件資訊。
此外,將這項資訊簽入原始碼控管系統,您、團隊成員和 CI/CD 管道每次都能使用相同的依附元件版本進行建構。
我們很高興宣布,Lightbuild 已在 Android Studio Canary 中推出早期預先發布版,並可透過獨立 CLI 工具使用。
請注意,這個 Lightbuild 版本仍處於實驗階段,因此不具備建構及維護正式版應用程式所需的所有功能。
請繼續使用 AGP 和 Gradle 處理正式版應用程式,並在試用和實驗專案中試用 Lightbuild。
歡迎立即前往 goo.gle/lightbuild 體驗,並提供寶貴意見,協助我們持續改良產品。
接下來,我會將簡報交給 Scott,由他展示 Lightbuild 的實際運作情形。
謝謝,Juan。
我是 Scott Myers。
我是 Android 開發人員關係工程師。我們開發 Lightbuild 已有一段時間,很高興今天能向大家展示如何實際操作和體驗。
因此,請先前往 Juan 提到的連結 goo.gle/lightbuild,或直接搜尋 Lightbuild。
接著,您應該會看到這個說明文件頁面,其中包含開始使用所需的所有步驟,包括安裝 Android Studio 的 Canary 版本,因為請記住,這仍處於預先發布版,尚未在 Android Studio 的穩定版中推出。
此外,您也可以安裝 Lightbuild CLI,充分發揮 Lightbuild 的代理功能。
設定完成後,就像我這裡的機器一樣,我已執行最新版 Android Studio Canary。
現在,我將逐步建立 Lightbuild 示範專案,並示範如何立即著手。
首先,我會前往「New Project」精靈。
我會選擇「Empty Activity」,然後點選「Next」。
現在,您會看到正常的專案詳細資料畫面,但底部多了一個新選項。
在建構設定語言下方,您可以選擇 Lightbuild。
在你點選「完成」前,系統會提醒你這是實驗功能。
您會看到專案立即與 IDE 同步並啟動,可供我們使用。
現在來看看一般 Lightbuild 專案的結構。
這是建立新應用程式時,系統提供的預設 Android 範本。
只會顯示「Hello, world!」。
因此,這是最簡單的入門方式。
您會看到專案的根層級有一個名為 project.lightbuild.yaml 的檔案。
這會提供整個專案的全域設定。
因此,您可以在這裡為專案命名、列出專案中的所有模組、指定提取依附元件的外部存放區,以及全域套用至專案不同部分的版本。
我們可以看到這裡有兩個模組:app 和 app-core。
這是因為所有 Lightbuild 專案都至少有兩個模組。
這是因為至少需要一個應用程式模組和一個程式庫模組。
我稍後會說明原因。
首先,來看看這個應用程式模組。
如果在這裡展開,您會看到模組的根層級有一個 lightbuild.yaml 檔案,每個模組都會有這個檔案。
這裡有一些基本資訊。
我們正在開發 Android 平台,
這個模組的類型是應用程式。
您可以列出 SDK 目標版本、應用程式 ID 等,然後列出這個應用程式模組依附的所有模組。
這個應用程式模組與標準 Android 範本稍有不同,有趣的是,來源資料夾中沒有任何內容。
因此,Lightbuild 的應用程式模組不含任何原始碼。
這是因為這個應用程式模組不會經常變更,但需要一些時間建構。
因此,如果將所有應用程式程式碼都保留在程式庫模組中,每次建構作業都會更快完成,因為不必重新計算及重新封裝應用程式模組中的所有內容。
接下來,我們來看看 app-core 模組,也就是這個應用程式模組依附的程式庫模組。
您可以看到這個模組確實有原始碼。
這裡有我們的主邏輯。
只會顯示「Hello, world!」。
如果查看這個模組中的 lightbuild.yaml 檔案,會發現其類型為程式庫。
這裡也會設定一些 SDK 版本號碼,但會列出這個模組中所有的外部依附元件。
此外,這個檔案也會宣告單元和檢測設備測試。
接下來,我們來看看您可能注意到的另一個檔案,Juan 稍早也提過,每個模組中都有一個 resolved.deps 檔案。
這個檔案由 Lightbuild 自動生成。
因此,您不應手動編輯,但其中會包含這個模組中所有已解析的依附元件清單。
因此,所有依附元件和轉換依附元件都已在這裡。
這表示在 IDE 中開啟應用程式或建構應用程式時,您不必再費心處理這項作業,因為系統已預先處理完畢,並已簽入專案。
接下來,我們來看看 Lightbuild 如何透過專案同步功能,實際改善開發人員體驗。
現在,我回到根層級 project.lightbuild.yaml,這裡的全域設定會列出應用程式中的所有模組。
通常,編輯設定或建構設定檔時,您會注意到畫面上出現同步按鈕,但需要一些時間才能處理完畢,因為 Juan 剛才提到,系統必須執行所有建構指令碼,才能執行部分建構作業,然後將該模型與 IDE 同步。
我們來對這個小專案進行重大變更。
我們只會刪除其中一個模組。
您可以看到,在我按下儲存按鈕之前,這個模組已被 IDE 識別,因為您可以看到這裡它是粗體的。
它辨識了來源目錄和測試目錄。
變更後,只要按下儲存,這個模組就會立即從專案中消失。
如果再次復原變更並儲存,就會立即恢復。
以上就是 Lightbuild 為專案帶來的快速 IDE 同步處理範例。
此外,您也可以在 Android Studio 中執行所有慣用的標準指令。
您可以按下執行按鈕。
系統會編譯應用程式,並在這裡執行。
這個示範應用程式不大,但我會放大畫面,顯示「Hello Android」字樣。
您可以像平常一樣執行測試,只要前往測試檔案,然後從空白邊執行即可,就像這樣。
實際上,系統會在背景叫用 Lightbuild 來執行這些測試。
因此,一切都會如預期運作。
接下來,我想說明如何在 Android Studio 以外的環境,使用 Lightbuild 搭配其他代理流程。
這時就能使用指令列。
因此,在 Lightbuild 的 CLI 中,我會執行基本說明指令。
沒錯,今天你在這項專案中看到的所有錯字,都是我造成的。
Lightbuild 內建多個指令,例如…抱歉,我是在專案外執行這個指令。
它一直這樣告訴我。
是,現場示範。
首先,在執行任何 Lightbuild 指令前,我會先建立 Lightbuild 專案。
為此,我將使用 android create,這是我們用於建立新專案範本的標準指令列工具。
我會使用 empty-activity-lightbuild 範本,將應用程式命名為 Lightbuild Demo,並放入 demo 輸出目錄。
現在,如果我進入該目錄並輸入 lightbuild -h,就會看到 Lightbuild 提供的所有指令。
因此,我們有許多您預期的功能:建構、清理、測試。
但也有一些新功能。
resolve 指令會實際執行專案的依附元件,並產生先前展示的 resolved.deps 檔案。
此外,您和代理還能使用查詢指令,進一步瞭解專案結構。
首先,我來展示一下新的查詢指令。
因此,如果我使用指令列查看這個專案的結構,會發現它與 Android Studio 示範中的結構相同。
但這並未提供太多有關專案配置的資訊。
因此,如果我執行 Lightbuild 查詢,並查看這個應用程式模組,我會使用這個特殊語法,表示「顯示這個應用程式模組下的所有內容」。
並提供這個精美的表格,列出我可以在應用程式模組中建構的不同目標。
因此,它有偵錯和發布二進位檔的 APK 和 AAB。
如果只執行應用程式目標,系統會建構所有內容。
您也可以指定以 JSON 格式輸出。
這樣一來,抱歉。
再次強調,我今天的所有錯字都是真實的。
我會使用互動式 Lightbuild 說明,確保操作正確。
咦…
應該可以。
現在我們來做個小測驗
如果有人能告訴我哪裡做錯了,請在演講結束後與我聯絡。
不過,除了這個表格,您也可以將 Lightbuild 指令輸出為 JSON,方便代理程式使用。
--format json…
格式。
抱歉。
感謝您!
這是開發人員的即時意見回饋。
感謝您!
好的,沒錯,還有輸出指令,我也可以示範,或許需要你的協助。
因此,如果我輸出檔案而非目標,就會看到建構作業中所有不同二進位檔的位置。
因此,您和代理程式可以透過 Lightbuild,使用指令列探索及進一步瞭解專案。
接著,顯然就是我稍早提到的 lightbuild resolve 指令,會產生所有 resolved.deps 檔案。
該版本也提供一些額外功能。
舉例來說,這個鎖定的依附元件參數,不只會產生這些檔案,還會實際比較檔案內容與您在建構設定中宣告的依附元件。
如有任何差異,系統會通知您,並導致建構作業失敗。
因此,這些已解析的依附元件檔案可以做為鎖定檔案,例如,如果您在 CI/CD 系統中建構應用程式以用於正式環境,您會想知道在建構期間是否有任何依附元件發生變更。
此外,Lightbuild 內建測試功能,您也可以直接從指令列執行這個程式庫模組下的所有測試。
最後,我想再介紹一項功能。
只是它也提供說明,可提供您可使用的所有參數和子指令的所有建構的完整清單。
代理可使用這項功能,因此這是代理的輸出內容。
現在我們來做個小測驗
我們已經看過一些使用 Lightbuild 的簡單專案,現在我想展示一個更具野心的專案。
Android 團隊提供了一個範例應用程式,名為「Now in Android」,其中包含一些最新的 Android 功能,並展示如何使用這些功能,以及一些最佳做法。
這是一個高度模組化的應用程式。
我認為這項課程分為 32 個不同的單元。
GitHub 中的畫面如下。
不過,我會切換回 Android Studio,因為我已經事先使用過代理。
我正在使用 Gemini Argon,將 Now in Android 專案轉換為 Lightbuild。
因此,這不是我們發布的內容,只是我個人製作的內容。
您可以看到,雖然 project.lightbuild.yaml 中的這項專案包含所有這些不同的模組,但開啟速度仍然非常快,而且與這個 IDE 同步的速度也很快。
這個專案還有一個值得注意的地方,就是它使用了一些建構變種版本或特殊建構設定,以便同時擁有示範建構和正式版建構,每個建構呈現應用程式的方式略有不同。
示範版本會使用內建資料來源,而正式版則會實際連上網路並提取資料。
如要使用 Lightbuild 處理不同的建構設定或變種版本,請前往應用程式模組,並指定該模組為示範應用程式。
因此,它會依賴所有核心元件,但也會拉入專為應用程式試用版設定的特殊設定。
因此,您可以透過這種方式擁有多個應用程式模組。
每個變種版本都代表一個應用程式版本,例如付費版或免費版。
此外,應用程式模組本身不含程式碼,因此建構速度更快。每當程式庫變更時,只需重新編譯這些程式庫,即可再次建構應用程式。
接著來看看這個 Now in Android 應用程式是否已成功使用 Lightbuild 建構,並包含所有 32 個不同的模組。
沒錯,就是這樣。
另外,我們從這類實驗中發現,Lightbuild 並不支援您可能需要的所有建構功能。
舉例來說,Now in Android 應用程式需要 Hilt 外掛程式才能使用 Hilt,但 Lightbuild 尚未支援這類功能。
因此,我的代理能夠找出解決方法,在不大幅變更專案程式碼的情況下,仍能加入 Hilt 支援。
這些模組中的所有程式碼都與原始存放區相同。
不過,在實驗和示範 Lightbuild 時,請務必記住,目前專案中的某些建構設定可能不受支援。
因此,Lightbuild 目前仍是預先發布版,僅在 Android Studio Canary 中提供。
// build.gradle.kts
android {
compileSdk = 37
buildTypes {
debug {
// Custom logic in build script
val commit = providers.exec {
commandLine("git", "rev-parse",
"--short", "HEAD")
}.standardOutput.asText.get()
.trim()
versionNameSuffix = "-$commit"
}
}
}// build.gradle.kts
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.compose)
}
val gitCommit = providers.exec {
commandLine("git", "rev-parse", "--short", "HEAD")
}.standardOutput.asText.get().trim()
android {
namespace = "com.example.app"
compileSdk = 37
defaultConfig {
minSdk = 24
buildConfigField("String", "GIT_COMMIT",
"\"$gitCommit\"")
}
buildFeatures {
compose = true
buildConfig = true
}
}
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics)
...# lightbuild.yaml
group: "com.example"
version: "1.0.0"
platform: android
type: library
android:
namespace: "com.example.app"
compileSdk:
version:
release:
apiLevel: 37
minSdk:
version:
release:
apiLevel: 24
dependencies:
maven:
- androidx.core:core-ktx:1.10.1
- androidx.lifecycle:lifecycle-runtime-ktx:2.6.1
- androidx.activity:activity-compose:1.8.0