Android應用構建速度提升的十個小技巧
應用的構建速度會直接影響開發效率,本文將帶您通過改造一個 Android 應用: “Google 追蹤圣誕老人 (Google Santa Tracker)” 來為大家提供十個小技巧,幫助提升應用的 Gradle 構建速度,當我們應用了所有的小技巧之后,該演示應用的構建速度快了三倍以上。
其次,在我們開啟速度提升調優之前,來了解本次三個性能指標的說明:
-
全量構建,也就是重新開始編譯整個工程的 debug 版;
-
代碼增量構建,指的是我們修改了工程的 Java / Kotlin 代碼;
-
資源增量構建,指的是我們對資源文件的修改,增加減少了圖片和字符串資源等。
小技巧 1: 使用最新版本的 Android Gradle 插件
每次 Android Gradle 插件的更新都會修復大量的 bug 及提升性能等新特性,因此保持最新的 Android Gradle 插件版本有非常大的必要。
從 3.0 版本開始,我們將通過 google() 的 Maven 倉庫分發新的 Android Gradle 插件,所以需要在 repositories 處加入 google() 以獲得最新的插件更新 (現在的 Android Studio 新建工程的時候會默認加入 google() 的 Maven 倉庫指向)。
這是將 Android Gradle 插件版本從 2.x 更新到 3.0.0-alpha1 之后得到的結果 (這里的演示是基于 3.0.0-alpha1 版本,隨著插件版本的更新,性能的提升會更加明顯),我們可以看出,全量構建一次應用的時間直接減少了 25%,代碼改動的增量構建減少了將近 40%,資源改動的增量構建也減少了 16%。
小技巧 2: 避免激活舊版的 Multidex
啟用 multidex https://developer.android.google.cn/studio/build/multidex.html
如果您是通過 Android Studio 的運行/調試按鈕來執行構建,那么無需考慮這個問題,新版本的 Android Studio 會自動檢測連接的設備和模擬器,如果系統的 API 級別大于 21 則進行原生的 multidex 支持,同時會忽略工程里對最低 API 級別 (minSdkVersion) 的設置。
這一次的性能改進結果效果也非常明顯 (灰色的線條是最初的結果),在全量構建的時候我們又降低了 5.5 秒的時間,而在代碼改動的增量構建里時間減少了 50% 以上,資源改動的增量構建與之前的時間相同。
小技巧 3: 禁用 Multiple APK 構建
禁用多 APK 構建不能僅僅在 splits 里設置,因為這里的設置對工程里所有的構建變體都是可見的。正確的禁用多 APK 構建的方法是創建一個屬性來做判斷,這里我們設置了一個名為 “devBuild” 的屬性,在構建的過程中把這個值傳給 gradle,此時 gradle 會將 splits.abi.enable 和 splits.density.enable 設置為 false,它就不會生成多個 APK 了。
在 Android Studio 里,您可以通過偏好設置,構建、執行和部署分類里,選擇編譯器選項來為命令行加入參數: -PdevBuild,這樣每次在構建的時候 Android Studio 會把這個值傳遞給 gradle 以避免生成多個 APK。
如上圖所示,這是我在禁用了多 APK 之后的效果,各項指標都在繼續降低。
-
Multiple APK
https://developer.android.google.cn/google/play/publishing/multiple-apks.html
-
構建變體
https://developer.android.google.cn/studio/build/build-variants.html
小技巧 4: 最小化使用資源文件
這里我們看到了較大程度上的改觀,全量構建的時間又降低了 6 秒,增量構建的時間也分別降低了 20% 以上。
小技巧 5: 禁用 PNG 壓縮
如果要避免使用 PNG 壓縮,我們可以在小技巧 3 里提到的,在 devBuild 屬性里加入 aaptOptions.cruncherEnabled = false 來實現,在構建的過程中把這個值傳給 gradle,它就可以避免執行 PNG 壓縮命令了。
這可以看到全量構建又減少了 9 秒的時間,這也是因為 Google 追蹤圣誕老人應用里有 3,500 多張 PNG 圖片,這要花費大量的時間進行壓縮計算,所以這方面的效率提升顯得很明顯,而其他增量構建只是維持了之前的情況。
小技巧 6: 使用 Apply Changes
從 Android Studio 3.5 版開始 (3.5 版目前在 Beta 構建渠道發布),開發者們可以使用 Apply Changes 功能來提高構建性能,它可以讓代碼和資源的改動直接生效而無需重啟應用,有時候甚至無需重啟當前的 Activity。與 Instant Run 的實現方式不一樣,Apply Changes 充分利用了 Android 8.0 以上版本操作系統的特性進行運行時檢測,從而動態的對類進行重新定義。因此,如果您希望使用 Apply Changes,則需要讓您的工程運行在 Android 8.0 (API級別26) 以上的真機或者模擬器上。
小技巧 7: 避免被動的改動
這個例子里,我們故意在構建腳本中加入里一些搗亂的代碼以展現其帶來的損失。同時也舉一個在使用 Crashlytics 時的實際例子,這個插件默認會為每次構建中都加入唯一 ID 作為構建標識,這會帶來不必要的時間損失,您可以通過在構建腳本里加入 ext.alwaysUpdateBuildId = false 來避免這個,當然也可以選擇在開發階段完全關閉 Crashlytics。
小技巧 8: 不使用動態版本標識
Gradle 提供了一個非常方便的依賴庫版本號管理功能,方便開發者們通過使用一個加號 “+” 標識希望使用這個依賴庫的最新版本。但是使用動態版本有幾個風險,從性能角度來說,Gradle 會每隔 24 小時去檢查一次依賴庫的更新,如果您的依賴庫很多,而且都使用了動態獲取最新版本的這個設定,那會對構建時候的性能產生一定的影響。
即使您不是特別在意這些性能損耗,但是它仍然是有風險的——依賴庫的版本更新會讓您的構建充滿不確定性,可能兩周之后您就在構建一個完全不一樣的工程了,因為依賴庫代碼的更新對開發者們是不可見的。
小技巧 9: Gradle 內存分配調優
小技巧 10: 開啟 Gradle 構建緩存
關于 Gradle 構建緩存 https://docs.gradle.org/current/userguide/build_cache.html
總結
代碼倉庫 https://github.com/jmslau/santa-tracker-android 官方文檔 https://developer.android.google.cn/studio/build/optimize-your-build