一. 前景
隨著Android平臺的持續(xù)成長谈秫,Android應用的大小也在增加。當應用及其引用的庫達到特定大小時卤妒,會遇到構(gòu)建錯誤息尺,指明你的應用已達到Android應用構(gòu)建架構(gòu)的極限。一般情況下贮竟,你會獲得類似的錯誤信息:
Dex: The number of method references in a .dex file cannot exceed 64K.
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
二. MultiDex
2.1. 官方方案
Dex文件64K方法數(shù)的限制已經(jīng)被提及過很多次丽焊,Android官方也提供了MultiDex來解決這一問題。
2.2. 局限性
官方文檔中也指出了MultiDex的局限性:
- 啟動期間在設備數(shù)據(jù)分區(qū)中安裝 DEX 文件的過程相當復雜咕别,如果輔助 DEX 文件較大技健,可能會導致應用無響應 (ANR) 錯誤。在此情況下惰拱,您應該通過 ProGuard 應用代碼壓縮以盡量減小 DEX 文件的大小雌贱,并移除未使用的那部分代碼啊送。
- 使用 Dalvik 可執(zhí)行文件分包的應用可能無法在運行的平臺版本早于 Android 4.0(API 級別 14)的設備上啟動。
- 使用 Dalvik 可執(zhí)行文件分包配置的應用發(fā)出非常龐大的內(nèi)存分配請求欣孤,則可能會在運行期間發(fā)生崩潰馋没。盡管 Android 4.0(API 級別 14)提高了分配限制,但在 Android 5.0(API 級別 21)之前的 Android 版本上降传,應用仍有可能遭遇這一限制篷朵。
在將應用配置為支持使用64K或更多方法引用之前,開發(fā)者應該采取措施減少應用代碼調(diào)用的引用總數(shù)婆排,包括由應用代碼或包含的庫定義的方法声旺。下列策略可幫助您避免達到 DEX 引用限制:
- 檢查您的應用的直接和傳遞依賴項 - 確保您在應用中使用任何龐大依賴庫所帶來的好處大于為應用添加大量代碼所帶來的弊端。一種常見的反面模式是段只,僅僅為了使用幾個實用方法就在應用中加入非常龐大的庫腮猖。減少您的應用代碼依賴項往往能夠幫助您規(guī)避 dex 引用限制。
- 通過 ProGuard 移除未使用的代碼 - 為您的版本構(gòu)建啟用代碼壓縮以運行 ProGuard赞枕。啟用壓縮可確保您交付的 APK 不含有未使用的代碼澈缺。
三. 工具
由于MultiDex存在的局限性,官方也給出了上述的兩個策略來輔助減少應用代碼調(diào)用的引用總數(shù)炕婶。
在實施這兩個策略之前姐赡,我們需要一個好用的工具來統(tǒng)計當前應用代碼的方法數(shù),在添加一個依賴庫之后古话,需要評估該依賴庫會引入多少方法雏吭,是否值得引用。
3.1. DexHelper
一款分析Dex文件的Gradle插件陪踩,在APK打包的同時杖们,輸出APK包中的dex文件相關信息: 引用方法數(shù)等。實現(xiàn)原理參考的官網(wǎng)Dex 格式肩狂,根據(jù)Dex文件格式摘完,解析APK包中的.dex二進制文件,獲取該dex文件中方法總數(shù)傻谁。
- 修改父項目build.gradle孝治,添加依賴
com.ximsfei:dexhelper:version
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// 添加依賴
classpath 'com.ximsfei:dexhelper:version'
}
}
注: 最新version,以官方地址為準
- 修改子項目build.gradle审磁,應用插件
com.ximsfei.dexhelper
apply plugin: 'com.android.application'
// 應用插件
apply plugin: 'com.ximsfei.dexhelper'
- 運行谈飒,通過assemble*命令打包apk,自動輸出結(jié)果
$ ./gradlew assemble -q
DexHelper: apk file -> app-debug.apk
DexHelper: dex file -> classes.dex
DexHelper: method size -> 27022
DexHelper: apk file -> app-release-unsigned.apk
DexHelper: dex file -> classes.dex
DexHelper: method size -> 27021
四. 總結(jié)
在選擇解決方案時态蒂,利用好的工具來評估實施方案的價值杭措,提高代碼運行效率,降低應用本身的體積钾恢,是每個開發(fā)者需要努力去做的手素。使用MultiDex來解決項目日益增長帶來的問題鸳址,不如在開發(fā)的過程中,將點滴細節(jié)做到極致泉懦。小工具大用途稿黍,DexHelper可以幫你將應用做到小而美。