較長的構(gòu)建時間將會減緩項目的開發(fā)進度,特別是對于大型的項目,app的構(gòu)建時間長則十幾分鐘,短則幾分鐘,長的構(gòu)建時間已經(jīng)成了開發(fā)瓶頸,本篇文章根據(jù)Google官方文檔,加上自己的一些理解提供一些提升app構(gòu)建速度的優(yōu)化建議。
1. 為開發(fā)環(huán)境創(chuàng)建一個變體
有許多配置是你在準備app的release 版本的時候需要,但是當你開發(fā)app的時候是不需要的,開啟不必要的構(gòu)建進程會使你的增量構(gòu)建或者c
LEAN構(gòu)建變得很慢,因此需要構(gòu)建一個只保留開發(fā)時需要配置的變體,如下例子創(chuàng)建了一個dev和prod變體(prod 為release 版本的配置)。
2 . 避免編譯不必要的資源
避免編譯和包含你沒有測試的資源(比如添加的一個本地的語言和屏幕密度資源),你可以只在你的’dev’ flavor下指定一種語言和一個屏幕密度,如下:
上面的配置將會限制dev 變體只使用 english string 資源和 xxhdpi 屏幕密度資源。
3 . 配置debug 構(gòu)建的Crushlytics為不可用狀態(tài)
在debug 構(gòu)建狀態(tài)下,如果你不需要運行崩潰上報,你可以將這個插件設置為不可用狀態(tài)來提升你的構(gòu)建速度,如下:
上面只是舉個例子,Crushlytics 為崩潰上報分析工具,在開發(fā)的時候我們可能不需要,因此不需要打開,在我們實際開發(fā)中,像崩潰上報SDK,數(shù)據(jù)統(tǒng)計SDK等(如 友盟統(tǒng)計、GrowingIO、百度統(tǒng)計)在開發(fā)階段都設置為不可用,來提升構(gòu)建速度。
4 . 用靜態(tài)的構(gòu)建配置值來構(gòu)建你的Debug版
一般地,在你的debug 構(gòu)建時,為manifest文件或者資源文件配置使用靜態(tài)/硬編碼的值。如果你的manifest或者資源文件的值每次構(gòu)建都需要動態(tài)更新,那么Instant Run 無法執(zhí)行代碼交換-它必須重新構(gòu)建和安裝新的APK。
例如,使用動態(tài)的version codes ,version names ,resources或者其他更改manifest文件的構(gòu)建邏輯,每次你想執(zhí)行一個修改都會構(gòu)建全部APK,即使實際的修改可能僅僅只需要熱交換。如果這些構(gòu)建配置是需要動態(tài)配置的,那么將它們從你的release 構(gòu)建變體中分離出來,并且在你的debug 構(gòu)建中保留它們的靜態(tài)值。像下面build.gradle 文件顯示的這樣:
5 . 用靜態(tài)的版本依賴
當你在build.gradle文件中聲明依賴的時候,你應該避免在版本號結(jié)束的地方使用+號,比如:com.android.tools.build:gradle:2.+ 因為Gradle的檢查更新,用動態(tài)的版本號會導致未知的版本更新、使解決版本的差異變得困難和更慢的構(gòu)建。你應該使用靜態(tài)或者硬編碼版本號來代替。如:com.android.tools.build:gradle:2.2.2 。
6 . 使 on demand 配置為enable 狀態(tài)
為了讓Gradle能夠確切的知道該如何構(gòu)建你的APP,在每次構(gòu)建之前,構(gòu)建系統(tǒng)配置工程的所有modules和其他依賴(即使你只想構(gòu)建或者測試一個modules),這使得大型的多module 工程的構(gòu)建速度變得很慢。告訴Gradle僅僅配置你想要構(gòu)建的Modules,用如下步驟使 on demand 配置可用
(1) 在菜單欄上選擇 File -> Settings(如果是Mac上 ,選擇 Android Studio ->Preferences)
(2) 導航到 Build,Execution,Deployment -> Compiler
(3) check Configure on demand 復選框
(4) 點擊 OK
如圖:
7 . 創(chuàng)建 library 模塊
檢查你app中的代碼,將可模塊化的代碼抽取一個Android Library module,通過這種方式模塊化你的代碼將允許構(gòu)建系統(tǒng)僅僅只編譯那些有改動的模塊,并將其構(gòu)建結(jié)果緩存下來以被后面的構(gòu)建使用。同樣的配置了 on demand 和 parallel project execution (project 并行執(zhí)行) 將更加高效(當你打開這些特性時)。
8 . 為自定義構(gòu)建邏輯創(chuàng)建Tasks
在你創(chuàng)建了 build profile (build profile 后文會講)之后,如果顯示構(gòu)建時間相對長的一部分時間花在“configure project(配置工程)階段,那么請 review 你的build.gradle 腳本,并且查找可包含到自定義Gradle Task中的代碼,通過將一些構(gòu)建邏輯移動到一個task 中,當需要的時候才運行,結(jié)果能被緩存用于后續(xù)的構(gòu)建,并且這個構(gòu)建邏輯可以并行執(zhí)行(如果你開啟了 并行執(zhí)行project),更多詳細信息請閱讀Gradle官方文檔。 official Gradle documentation
小提示:
如果你的構(gòu)建包含了大量的自定義任務tasks,你可能想清理你的build.gradle文件,通過自定義task classes (也就是自定義Gradle 插件啦),將你的classes 添加到 project-root/buildSrc/src/main/groovy/目錄下,Gradle將自動包含它們到class path ,為項目的所有build.gradle文件。
9 . 配置 dexOptions 和 開啟 library pre-dexing(dex預處理)
先補充一個知識點:Dex-in-process:新發(fā)布的Android Studio 2.1增加了一個新的特性:Dex In Process,可以極大的加快重新編譯的速度,同樣也能提高Instant Run的性能。(第10條優(yōu)化建議會說到)
詳情請看Faster Android Studio Builds with Dex In Process
Android 插件提供了 dexOptions script block ,因此你可以配置相應的 DEX 構(gòu)建特性,它們可以提高構(gòu)建速度:
(1)preDexLibraaies : 聲明是否對依賴的庫進行dex 預處理來使你的增量構(gòu)建更快速,因為這個特性可能會使你的c
LEAN 構(gòu)建變慢,因此在你的持續(xù)集成服務器上你可能想關閉這個特性。
(2) maxProcessCount : 設置最大的線程數(shù)量使用當運行 dex-in-process時,默認值是4。
(3)javaMaxHeapSize: 為DEX 編譯器 設置最大的堆大小,相對于設置這個屬性,你應該增加 Gradle的 堆大小(這個堆大小dex-in-process可用的時候?qū)EX 編譯器有效)
例子:
你應該增加它們的值來測試一下這些設置,然后通過profile觀察效果,當你為這個進程分配太多資源的時候,可能會得到一個負面的影響。
10 . 增加Gradle的堆大小 和開啟 dex-in-process
Dex-in-process 允許多個DEX 進程運行在一個單獨的VM 中,這使得增量構(gòu)建和清理構(gòu)建變得更快。默認情況下,通過Android Studio2.1 或者更高版本創(chuàng)建的新項目分配了足夠的內(nèi)存來開啟這個特性,如果你沒有使用Android Studio 2.1 或者更高的版本創(chuàng)建項目,你需要給Gradle后臺駐扎程序設置至少1536MB 的堆大小內(nèi)存。默認如下圖:
下面的例子在gradle.properties中將Gradle 堆內(nèi)存大小設置為 2048MB:
org.gradle.jvmargs = -Xmx2048m //設置Gradle 堆大小 2G
在一些大型的項目上,為Gradle堆分配更多的內(nèi)存當然更有利,然而,如果你用的是一個小內(nèi)存的機器,你可能需要給IDE配置更少的內(nèi)存,想知道如何改變分配給IDE資源的數(shù)量和Gradle 對構(gòu)建表現(xiàn)的影響,請看profiling your build這一條。
如果在你的Module build.gradle 文件中為android.dexOptions.javaMaxHeapSize定義了一個值,那么你需要給Gradle的堆大小設置 的值為比javaMaxHeapSize多512MB,并且滿足至少為1536MB。舉個例子:在build.gradle中設置javaMaxHeapSize `為1280MB,那么你就要給Gradle堆大小設置 至少1792MB(1280 + 512),當然了,設置大一點更佳。
build.gradle:
11 . 將圖片轉(zhuǎn)為 WebP格式
WebP是一種圖片文件格式,它提供了像JPEG一樣的有損壓縮和像PNG一樣的透明支持,但是同時它的壓縮質(zhì)量比JPEG或者PNG任何一個都更好,減小Image文件的大小,而不用在構(gòu)建時做壓縮,因此它能提高構(gòu)建速度,尤其是你的APP使用了大量的圖片資源。但是有一點,在解壓WebP格式的圖片的時候,你的設備的CPU使用將小幅度增加。 用Android Studio 可以很方便的轉(zhuǎn)WebP格式,詳情請看convert your images to WebP.
小提示:此外,將工程里面的圖片轉(zhuǎn)為webP格式也是優(yōu)化APK體積的一個方向,webp是Android 原生4.0就開始支持的,它能提供和JPEG和PNG相同質(zhì)量的圖片但是size 更小。沒有任何適配問題。
12 . 禁止使用 PNG crunching
如果你不能(或者不想)轉(zhuǎn)換你的PNG格式圖片為WebP,你仍然可以通過禁止每次構(gòu)建app都自動壓縮圖片來提升構(gòu)建速度,要禁止這項優(yōu)化,在build.gradle 的添加如下代碼:
13 . 使用 Instant Run
Instant Run顯著的減少了更新app的時間,它通過推送確定的代碼、資源變更而不用構(gòu)建一個新的app ,并且在一些情況下,甚至不用重啟當前的activity,在代碼變更后,使用Instant Run 通過點擊Apply Changes(黃色?圖標)。當你做了如下幾步,它會默認打開:
-
用debug 構(gòu)建變體來構(gòu)建你的app
-
在module層級的build.gradle中設置minSdkVersion為15或者更高
-
發(fā)布你的app 在Android 5.0(API level 21) 或者更高 點擊 Run
14 . 使用構(gòu)建緩存
在構(gòu)建你的工程的時候,構(gòu)建緩存存儲了Android Gradle插件生成的確定的產(chǎn)物(如 AAR包和遠程依賴的 pre-dexed)。當你使用緩存的時候,你的清理構(gòu)建更快是因為構(gòu)建系統(tǒng)后續(xù)構(gòu)建能夠簡單地重用它們的緩存而不用重新創(chuàng)建。
新的工程使用Android Gradle 插件2.3.0或者更高版本默認就開啟了構(gòu)建緩存(除非你手動關閉了),了解更多請閱讀Accelerate c
LEAN builds with build cache.
15 . 禁止使用注解處理器
Gradle 2.1后可以增量構(gòu)建Java,當使用注解處理器時增量構(gòu)建將不可用,如果可以,避免使用注解處理器,讓你從只構(gòu)建更改的類來獲益。(提升編譯時間)
16 . 分析你的構(gòu)建(Profile your build)
在大型的項目中(或者實現(xiàn)了大量自定義構(gòu)建邏輯),可能需要更加深入的了解構(gòu)建進程來尋找瓶頸,你可以通過分析構(gòu)建生命周期的各個階段 每個gradle task 執(zhí)行了多長時間。例如:如果你的構(gòu)建資料顯示Gradle 花了大量的時間來配置你的工程,這建議你需要將自定義構(gòu)建邏輯放在配置階段之外。另外,如果mergeDevDebugResources 任務 消費了大量的的構(gòu)建時間,這表明你需要將圖片轉(zhuǎn)換為WebP格式或者禁止PNG Crunching(第11,12 條優(yōu)化建議)
通過構(gòu)建分析來提升你的構(gòu)建速度通常需要在分析打開的情況下運行你的構(gòu)建,多次修改構(gòu)建配置,分析和觀察結(jié)果的變化。
生成和查看 build profile ,執(zhí)行下面步驟:
1),用Android Studio打開項目,選擇 View -> Tool Windows -> Terminal 打開命令行
2),執(zhí)行clean build 輸入下面的命令,當你分析你的構(gòu)建時,每次構(gòu)建之間需要執(zhí)行一個 clean build 操作,因為Gradle會跳過輸入沒有 改變的tasks,因此,第二個沒有改變輸入的構(gòu)建通常會運行得更快因為tasks 沒有重新運行,因此在構(gòu)建之間運行一個cleantask 保證你分析了全部的構(gòu)建進程。
//如果在Mac 或者 Linux上 用 ./gradlew
gradlew clean
3),選擇其中一個產(chǎn)品風味(product flavor) 執(zhí)行debug 構(gòu)建,比如:dev flavor,如下:
gradlew --profile --recompile-scripts --offline --rerun-tasks assembleFlavorDebug
命令分析:
--profile: 開啟profiling
--recompile-scripts: 強制腳本重新編譯跳過cache
--offline:禁止 Gradle獲取離線依賴,這是確保任何的延遲都是Gradle試圖更新依賴而導致,不會誤導你的分析數(shù)據(jù)。你應該先準備好構(gòu)建一次工程確保Gradle 已經(jīng)下載好并且緩存依賴。
--rerun-tasks:強制Gradle返回所有task 并且忽略任何task 優(yōu)化。
4),構(gòu)建結(jié)束后,project-root/build/reports/profile/ 目錄下:
profile_build.png
5),右鍵點擊profile_timestamp.html,選擇在瀏覽器中打開,你就會看到下面這張圖,你可以觀察報告中的每一個tab來了解你的構(gòu)建,比如Tasks Execution 顯示了每一個task執(zhí)行的時間。
profile_in_brower.png
task Execution 顯示每個task的執(zhí)行時長,如下圖:
task_execution.png
6),可選項:在Project 或者構(gòu)建配置做出任何修改之前,重復幾次步驟3,但是去掉--rerun-tasks標志,由于Gradle 試圖節(jié)省時間而不會重新執(zhí)行那些輸入沒有任何修改的task(它們被標志為UP-TO-DATE 在Task Execution tab下,如下圖:),你可以識別哪些任務沒有被執(zhí)行,例如,如果:app:processDevUniversalDebugManifest沒有被標記成UP-TO-DATE,那么它表示你的構(gòu)建配置是每一次構(gòu)建都動態(tài)更新Manifest文件的。然而,有一些task還是需要每次都執(zhí)行的,例如::app:checkDevDebugManifest
現(xiàn)在,你已經(jīng)有了一個構(gòu)建分析報告,你可以開始通過觀察構(gòu)建報告的每一個tab來尋找優(yōu)化時機,一些構(gòu)建配置是需要試驗的,因為在不同的項目或者工作空間中它們的獲益不一樣。比如,基于大量代碼的大型工程,它們可能獲益于使用混淆、清除無用代碼和縮減APK體積。然而,小型工程可能獲益于關閉混淆(混淆還是挺耗時的)。此外,在第內(nèi)存的機器上增減Gradle 的堆大小,也有可能起到反面作用。
17 . 項目組件化
對于大型的項目,可能上面這些優(yōu)化建議有一定的效果,但是構(gòu)建速度還是有些慢,那么就可以考慮組建化了,將項目拆分成一個個單獨的組件,開發(fā)環(huán)境每個module 都是一個APK,發(fā)布的時候,每個module都是一個lib 給主工程使用。篇幅有效,這里就不再詳細介紹組件化,現(xiàn)在組件化是一個趨勢,如果有精力或者有實力,組件化是一個很不錯的選擇。
最后
以上就是一些解決app構(gòu)建速度慢的優(yōu)化建議,如果你覺得你的工程構(gòu)建速度慢,你可以試一下這些優(yōu)化項。如有問題,歡迎評論區(qū)留言。如果你還有什么更好優(yōu)化建議,也可以在下面留言,我會追加文章后面。
核心關注:拓步ERP系統(tǒng)平臺是覆蓋了眾多的業(yè)務領域、行業(yè)應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業(yè)務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業(yè)務領域的管理,全面涵蓋了企業(yè)關注ERP管理系統(tǒng)的核心領域,是眾多中小企業(yè)信息化建設首選的ERP管理軟件信賴品牌。
轉(zhuǎn)載請注明出處:拓步ERP資訊網(wǎng)http://www.ezxoed.cn/
本文標題:Android優(yōu)化APP構(gòu)建速度的17條建議
本文網(wǎng)址:http://www.ezxoed.cn/html/support/11121520607.html