Speedup:專爲項目下Library project過多所設計的加速插件

背景

隨着app的持續迭代更新,新功能的持續集成等緣由。項目中的library project愈來愈多。android

特別是最近一兩年來。流行起來了組件化,這更是直接增長了不少的本地library project的數量。致使每次須要打包apk運行時,都會須要對全部module都進行再次編譯。嚴重影響打包速度。git

加速插件簡介

Speedup是一款專用於對多module環境下進行打包加速的gradle插件。主要依賴的基本原理有兩個:github

  1. 動態依賴替換
  2. 打包任務特性

插件地址

github.com/JumeiRdGrou…shell

動態依賴替換

咱們先來看看常規多module環境下的打包流程:api

從上圖能夠看到。每次打包的時候。都會通過如下幾個步驟:bash

  1. 對依賴的module進行進行打包編譯,生成各自library的aar依賴。
  2. 對aar依賴進行合併。包括classes.dex的合併、資源合併等。
  3. 將合併後的文件、資源進行打包,生成apk。

而若是。咱們使用maven依賴的方式進行依賴的話。編譯流程就會優化成下圖所示的方式:網絡

能夠看到。與上面直接使用module依賴的方式相比:使用Maven倉庫依賴的方式,因爲maven倉庫中提供的直接就是已打包好的aar依賴,因此直接幹掉了module -> aar打包編譯的過程,起到了加速編譯的做用!併發

因此,如今咱們就能夠得出第一個結論:使用maven依賴比使用module依賴更快速!app

因此這個時候。不少人的常規作法就是。想辦法將這些module依賴的library,編譯打包發佈到各自的遠程中央倉庫中去,這樣就能避免每次運行的時候都去進行額外編譯,從而節省時間了。maven

可是這種作法存在幾個問題:

  1. 絕大部分library並不穩定。須要常常修改使用,若放到遠程倉庫,修改起來很麻煩
  2. 遠程倉庫的version版本號惟一,每次進行修改後都會須要更新升級版本號再發布。多人協做時容易形成混亂且也不容易維護

因此將module打包發佈到遠程倉庫的作法,並不可取!

如今咱們來考慮一下,若是將倉庫設置在本地會怎樣?也就是說使用本地maven倉庫進行依賴管理。

咱們來列舉一下這裏使用本地依賴的優勢:

  • 本地倉庫中version不惟一

    便可以作到同版本覆蓋發佈,修改代碼後直接從新發布便可,不須要提高version版本。這也正是遠程倉庫所作不到的。可避免頻繁升級改動。

  • 本地倉庫不與網絡打交道

    讀取依賴更快速。事實上,遠程倉庫中所依賴的庫,也是先存放到本地倉庫中去再進行讀取的。

能夠看到,使用本地倉庫,能夠完美的解決頻繁發包的問題!由於若是你的library不須要頻繁修改的話,你確定也早就已經把它單獨拆出去放遠程倉庫中去了~

因此咱們只要解決依賴不統一的問題。那麼這個加速方案就算是完全打通了!

打包任務特性

打包任務這裏特指的assembleXXX任務。這個任務相信你們平時也見過無數次了。

此任務是由android插件所提供的,編譯、合併、打包一條龍的總線任務。平時咱們點擊運行按鈕、打包apk時。也是經過的調用此任務進行打包。打包後經過內置的adb命令將apk發送到手機並執行安裝。

這個任務有個很重要的特性。這裏我稱之爲按需加載特性

打個比方:假如咱們使用的組件化開發模式,項目依賴鏈以下圖所示:

上圖所示的依賴鏈,對組件化不熟的可能會比較懵逼。對組件化有興趣的能夠去這裏瞭解一下組件化的項目結構:聚美組件化實踐之路

這裏有三個可運行的殼工程。其各自殼工程的依賴鏈以下:

  1. [app shell 1] -> [component 1] -> [base library]
  2. [app shell 2] -> [component 2] -> [base library]
  3. [Main app] -> [component 1] & [component 2] -> [base library]

按需加載特性是指:在進行打包任務過程當中,打包任務只會觸發當前自身依賴鏈中的module進行編譯。而不會對別的非自身依賴鏈中的module進行編譯。

因此,當你運行app shell1的時候。這個時候會參與打包編譯的就是[app shell 1]、[component 1]、[base library]這三個module. 這就是按需加載特性

原理

基於以上分析,我創建了此Speedup插件。利用gradle腳本,方便的進行本地aar打包發佈,並經過對打包任務流程進行監聽,動態的將module依賴替換爲本地倉庫中的maven依賴。

流程圖

這裏我畫了個簡單的流程圖。便於直觀的理解此gradle插件的運行機制。

特性

  • 原理簡單:整個插件由三個文件組成,並有詳細註釋,很容易理解
  • 配置簡單:簡單得出乎你意料!
  • 不一樣機器配置獨享,不衝突:
  • 兼容性好:實現邏輯依賴最簡單的api。最大程度下降gradle版本升級時sdk改動形成的影響。

使用方式

依賴配置

在項目根目錄下添加依賴並添加應用插件

buildscript {
    repositories {
        // 添加jitpack倉庫地址
        maven { url "https://jitpack.io" }
    }
    dependencies {
        // 添加插件依賴
        classpath "com.github.yjfnypeu:Speedup:0.9"
    }
}
// 應用插件
apply plugin: 'speedup'
複製代碼

屬性配置

Speedup支持配置三種屬性,均配置於項目根目錄下的local.properties文件中。

  • speedup.enable:

    是否激活speedup插件。默認爲false,即不激活。這樣作的目的是爲了使得在發版機器上進行打包apk時。自動忽略speedup插件。進行全量編譯

  • localRepo:

    本地maven倉庫的地址。默認爲項目根目錄下的_repo文件夾。若你須要使用別的地址。在此配置個本地地址便可

  • excludeModules:

    因爲咱們開發的業務線的不一樣。不少時候咱們是須要對部分的module每次都進行即時編譯的:好比說如今正在作的功能。是須要對某個lib進行頻繁修改的。因此這個時候。就須要使用此屬性。指定此lib不須要進行加速。那麼每次運行時。都會對此lib進行編譯。

把全部屬性全放置於local.properties中,出於如下幾點考慮:

  • 每一個人所須要使用的配置方案不同,放於local文件中,能夠起到配置獨立的做用。
  • 發版apk不使用加速方案。通常打包發版apk的均運行在獨立的機器上.

配置示例

github上我提供了一個組件化demo地址, 此demo中有添加此插件配置使用。如下內容建議結合demo進行查看。

Android組件化demo展現

因爲本地配置是放置於local.properties文件當中。因此默認依賴下來是沒有開啓激活此插件的。能夠參考下方的配置:放入自身的local.properties中去。

speedup.enable=true
# 當須要排除多個module時,中間用英文的逗號隔開
excludeModules=:usercenter:componentusercenter
複製代碼

當配置speedup.enable爲true,而且同步完成以後。你就能夠在gradle任務列表中發現一組speedup任務:

能夠看到。speedup任務組中。含有大量的uploadXXX任務提供使用。這些任務都是在同步時根據各個library module自動生成的上傳任務。主要目的是將本地的library module方便的進行打包、編譯。併發布到本地的倉庫中去。提供使用。

當你使用upload進行本地打包發佈後,你就能夠在項目根目錄下的_repo文件夾下找到對應的打包出來的aar:

而後,你能夠試試直接運行。而且觀察右下角的Gradle Console控制檯輸出日誌。注意看全部執行的任務列表。就會發現:執行的gradle任務明顯減小了,而且被打包到本地中的module。並無被再次進行編譯。

這是由於已經在運行時。動態的將對應的module替換爲使用本地倉庫中的aar地址了。

以上便是此插件的整個用法示例。能夠總結爲如下幾步:

  1. 添加依賴、配置
  2. 執行upload任務進行本地發佈
  3. 直接運行。

upload任務列表說明

Speedup插件任務中,很重要的一點便是生成的upload任務列表了。此upload任務主要分爲三類:

  1. uploadAll

    做用:用於對項目中全部的library(除了excludeModules所指定排除的module)進行打包發佈。此任務默認將會對項目下全部的module執行clean操做。因此能夠保證打包出來的aar是不受數據污染的

    使用場景:在進行分支切換後、或者進行合併代碼後。此時不少module的數據都有修改。可使用此任務一次性所有從新打包上傳。

  2. uploadForClean

    做用:用於觸發項目下全部module的clean任務。將其build文件夾刪除。避免打包時出現數據污染。

    與AS自帶的clean任務不一樣。自帶的clean任務附帶了不少額外的任務,因此每次clean會很慢。而uploadForClean。只會觸發全部module自身的clean任務,對自身的build文件夾進行刪除,並沒有其餘額外操做。這樣clean的速度會獲得很大提高。

    此任務通常來講外部不須要直接使用。主要是內部直接提供給uploadAll進行使用

  3. uploadXXX

    做用:用於對指定的module進行從新打包發佈。好比uploadbaselib。此任務表明對baselib從新進行打包發佈。

相關文章
相關標籤/搜索