再見吧 buildSrc, 擁抱 Composing builds 提高 Android 編譯速度

前言

長期以來困擾咱們的一個問題就是構建速度,AndroidStudio 的構建速度嚴重影響 Android 開發者的工做效率,尤爲是更新一個版本號,致使整個項目從新構建,在網絡慢的狀況下,這是沒法忍受的。html

buildSrc 這種方式,在最近幾年是很是流行的,由於它有如下優勢:java

  • 共享 buildSrc 庫工件的引用,全局只有一個地方能夠修改它
  • 支持 AndroidStudio 自動補全

  • 支持 AndroidStudio 單擊跳轉

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

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.git

buildSrc的更改會致使整個項目過期,所以,在進行小的增量更改時,-- --no-rebuild命令行選項一般有助於得到更快的反饋。不過,請記住要按期或至少在完成後運行完整版本。github

彙總一句話就是說,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 應該是首選,由於它更易於維護、重構和測試代碼bash

什麼是 Composing builds

摘自 Gradle 文檔:複合構建只是包含其餘構建的構建. 在許多方面,複合構建相似於 Gradle 多項目構建,不一樣之處在於,它包括完整的 builds ,而不是包含單個 projects

  • 組合一般獨立開發的構建,例如,在應用程序使用的庫中嘗試錯誤修復時
  • 將大型的多項目構建分解爲更小,更孤立的塊,能夠根據須要獨立或一塊兒工做

buildSrc vs Composing builds

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

Composing-builds-vs-buildSr

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-buildSrc

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

Project-ComposingBuild

當修改了版本號,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 文件夾就能夠便可

參考文獻

結語

致力於分享一系列 Android 系統源碼、逆向分析、算法、翻譯、Jetpack 源碼相關的文章,能夠關注我,若是你喜歡這篇文章歡迎 star,一塊兒來學習,期待與你一塊兒成長

文章列表

算法

因爲 LeetCode 的題庫龐大,每一個分類都能篩選出數百道題,因爲每一個人的精力有限,不可能刷完全部題目,所以我按照經典類型題目去分類、和題目的難易程度去排序

  • 數據結構: 數組、棧、隊列、字符串、鏈表、樹……
  • 算法: 查找算法、搜索算法、位運算、排序、數學、……

每道題目都會用 Java 和 kotlin 去實現,而且每道題目都有解題思路,若是你同我同樣喜歡算法、LeetCode,能夠關注我 GitHub 上的 LeetCode 題解:Leetcode-Solutions-with-Java-And-Kotlin,一塊兒來學習,期待與你一塊兒成長

Android 10 源碼系列

Android 應用系列

工具系列

逆向系列

相關文章
相關標籤/搜索