使用Composing builds提升Android編譯速度

前言

長期以來困擾我們的一個問題就是構建速度,AndroidStudio 的構建速度嚴重影響 Android 開發者的工作效率,尤其是更新一個版本號,導致整個項目重新構建,在網絡慢的情況下,這是無法忍受的。

buildSrc 這種方式,在最近幾年是非常流行的,因為它有以下優點:

共享 buildSrc 庫工件的引用,全局隻有一個地方可以修改它

支持 AndroidStudio 自動補全

支持 AndroidStudio 單擊跳轉

有優點的同時也有缺點,來看一下 Gradle 文檔

A change in buildSrc causes the whole project to become out-of-date. Thus, when making small incremental changes, the –no-rebuild command-line option is often helpful to get faster feedback. Remember to run a full build regularly or at least when you’re done, though.

buildSrc的更改會導致整個項目過時,因此,在進行小的增量更改時,– –no-rebuild命令行選項通常有助於獲得更快的反饋。不過,請記住要定期或至少在完成後運行完整版本。

匯總一句話就是說,buildSrc 依賴更新將重新構建整個項目,那麼有沒有一種方法支持自動補全和單擊跳轉,有不用重新構建整個項目,Composing builds 就可以實現,接下來我們來演示一下 buildSrc 和 Composing builds 它們的 build 的時間,相關代碼我已經上傳到 GitHub 瞭:ComposingBuilds-vs-buildSrc

通過這篇文章你將學習到以下內容,將在文末總結部分會給出相應的答案

  • 什麼是 buildSrc?
  • 什麼是 Composing builds?
  • 如何使用 Composing builds 和 buildSrc
  • buildSrc 和 Composing builds 優勢劣勢對比?
  • Composing builds 編譯速度怎麼樣?
  • buildSrc 如何遷移到 Composing builds?
  • 管理 Gradle 依賴都有那幾種方式?以及效率怎麼樣?

這篇文章涉及很多重要的知識點,請耐心讀下去,我相信應該會給大傢帶來很多不一樣的東西。

Composing builds 和 buildSrc 對比

接下來我們來演示一下 buildSrc 和 Composing builds 它們的優勢劣勢對比,在分析之前,先來瞭解一下基本概念

什麼是 buildSrc

摘自 Gradle 文檔:當運行 Gradle 時會檢查項目中是否存在一個名為 buildSrc 的目錄。然後 Gradle 會自動編譯並測試這段代碼,並將其放入構建腳本的類路徑中, 對於多項目構建,隻能有一個 buildSrc 目錄,該目錄必須位於根項目目錄中, buildSrc 是 Gradle 項目根目錄下的一個目錄,它可以包含我們的構建邏輯,與腳本插件相比,buildSrc 應該是首選,因為它更易於維護、重構和測試代碼

什麼是 Composing builds

摘自 Gradle 文檔:復合構建隻是包含其他構建的構建. 在許多方面,復合構建類似於 Gradle 多項目構建,不同之處在於,它包括完整的 builds ,而不是包含單個 projects

  • 組合通常獨立開發的構建,例如,在應用程序使用的庫中嘗試錯誤修復時
  • 將大型的多項目構建分解為更小,更孤立的塊,可以根據需要獨立或一起工作

buildSrc vs Composing builds

為瞭正確對比這兩種方式,新建瞭兩個空的項目分別是 Project-buildSrc 和 Project-ComposingBuild,這兩個項目引用的依賴都是一樣的,Project-buildSrc 包含 buildSrc,Project-ComposingBuild 包含 Composing builds。

Project-buildSrc 和 Project-ComposingBuild 它們的結構都差不多,接下來我們來看一下,編譯速度 和 使用上有什麼不同。

編譯速度

Project-buildSrc 和 Project-ComposingBuild 這兩個項目,它們的 androidx.appcompat:appcompat 的版本是 1.0.2,現在我們從 1.0.2 升級到 1.1.0 來看一下它們 Build 的時間。

  • Project-buildSrc:修改瞭版本號 1.0.2 -> 1.1.0 重新 Build 用時 37s

  • Project-ComposingBuild:修改瞭版本號 1.0.2 -> 1.1.0 重新 Build 用時 8s

當修改瞭版本號,Project-buildSrc 項目 Build 的時間幾乎是 Project-ComposingBuild 項目的 4.6 倍( PS: 每個人的環境不同,時間上會有差異,但是 Project-buildSrc 的時間總是大於 Project-ComposingBuild )

在更大的項目中,網絡慢的情況下,這種差異會更加明顯,幾分鐘的構建都是常事,在 buildSrc 中做微小的更改,可能需要花很長時間構建,等待團隊其他成員在他們提取更改之後,都將導致項目重新構建,這個代價是非常昂貴的。

它們在使用上有什麼不同呢

Project-buildSrc

  • 在項目根目錄下新建一個名為 buildSrc 的文件夾( 名字必須是 buildSrc,因為運行 Gradle 時會檢查項目中是否存在一個名為 buildSrc 的目錄 )
  • 在 buildSrc 文件夾裡創建名為 build.gradle.kts 的文件,添加以下內容
plugins {
    `kotlin-dsl`
}
repositories{
    jcenter()
}
  • buildSrc/src/main/java/包名/ 目錄下新建 Deps.kt 文件,添加以下內容
object Versions {
    ......
    val appcompat = "1.1.0"
    ......
}
object Deps {
    ......
    val appcompat =  "androidx.appcompat:appcompat:${Versions.appcompat}"
    ......
}
  • 重啟你的 Android Studio,項目裡就會多出一個名為 buildSrc 的 module,實現上面演示的效果

Project-ComposingBuild

  • 新建的 module 名稱 versionPlugin
  • 在 versionPlugin 文件夾下的 build.gradle 文件內,添加以下內容
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // 因為使用的 Kotlin 需要需要添加 Kotlin 插件
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72"
    }
}
apply plugin: 'kotlin'
apply plugin: 'java-gradle-plugin'
repositories {
    // 需要添加 jcenter 否則會提示找不到 gradlePlugin
    jcenter()
}
gradlePlugin {
    plugins {
        version {
            // 在 app 模塊需要通過 id 引用這個插件
            id = 'com.hi.dhl.plugin'
            // 實現這個插件的類的路徑
            implementationClass = 'com.hi.dhl.plugin.Deps'
        }
    }
}

versionPlugin/src/main/java/包名/ 目錄下新建 Deps.kt 文件,添加以下內容

class Deps : Plugin<Project> {
    override fun apply(project: Project) {
    }
    companion object {
        val appcompat = "androidx.appcompat:appcompat:1.1.0"
    }
}

在 settings.gradle 文件內添加 includeBuild 'versionPlugin' 重啟你的 Android Studio

在 app 模塊 build.gradle 文件內首行添加以下內容,就可以實現上面演示的效果

plugins{
    // 這個 id 就是在 versionPlugin 文件夾下 build.gradle 文件內定義的 id
    id "com.hi.dhl.plugin"
}

ps:plugins{} 需要放在 app 模塊 build.gradle 文件內首行位置

Project-ComposingBuild 比 Project-buildSrc 多瞭兩步操作需要在 settings.gradle 和 build.gradle 引入插件,兩者在使用都是差不多的

如何快速使用 buildSrc

  • 訪問 ComposingBuilds-vs-buildSrc 拷貝 buildSrc 文件夾到你的項目的根目錄
  • 重啟你的 Android Studio,項目裡就會多出一個名為 buildSrc 的 module

如何快速使用 Composing builds

  • 訪問 ComposingBuilds-vs-buildSrc 拷貝 versionPlugin 文件夾到你的項目的根目錄
  • 按照上面的配置方式,分配在 settings.gradle 和 app 模塊的 build.gradle 引用插件即可

總結

總共從以下幾個方面對比瞭 Composing builds 和 buildSrc

  • 目錄結構:它們的基本目錄結構是相同的,可以根據自己的項目進行不同的擴展
  • 編譯速度:當修改瞭版本號,Project-buildSrc 項目 Build 的時間幾乎是 Project-ComposingBuild 項目的 4.6 倍( PS: 每個人的環境不同,時間上會有差異,但是 Project-buildSrc 的時間總是大於 Project-ComposingBuild )
  • 使用上的區別:Composing builds 比 buildSrc 多瞭兩步操作需要在 settings.gradle 和 build.gradle 引入插件

Project-buildSrc 和 Project-ComposingBuild 相關代碼已經上傳到 GitHub 瞭:ComposingBuilds-vs-buildSrc

到目前為止大概管理 Gradle 依賴提供瞭 4 種不同方法:

  • 手動管理 :在每個 module 中定義插件依賴庫,每次升級依賴庫時都需要手動更改(不建議使用)
  • 使用 ext 的方式管理插件依賴庫 :這是 Google 推薦管理依賴的方法 Android官方文檔
  • Kotlin + buildSrc:自動補全和單擊跳轉,依賴更新時 將重新 構建整個項目
  • Composing builds:自動補全和單擊跳轉,依賴更新時 不會重新 構建整個項目

buildSrc 如何遷移到 Composing builds?

如果當前項目使用的是 buildSrc 方式,遷移到 Composing builds 很簡單,需要將 buildSrc 內容拷貝的 Composing builds 中,然後刪掉 buildSrc 文件夾就可以即可

參考文獻

Organizing Gradle Projects

Composing builds

Android官方文檔,使用 ext 的方式管理插件依賴庫

以上就是使用Composing builds提升Android編譯速度的詳細內容,更多關於Android編譯Composing builds 的資料請關註WalkonNet其它相關文章!

推薦閱讀: