Android Multidex 的問題優化
降低啟動速度的問題
文章中提到的一點,在 Android 設備 4.4 及其之前的版本,當開啟 Multidex 的時候,啟動速度會延長 15% 。而 5.0及以上的設備因使用 ART 的方式,其默認支持多 dex 的加載。
NoClassDefFoundError 的問題
- 查看加載的類問題 在目錄 [buildDir]/intermediates/multi-dex/[buildType]/maindexlist.txt 中可查看在主 dex 文件中的類,(但并不是 100% 準確,可能會丟失一些類)
- 解決辦法:配置一個新的 multidex.keep 文件,用來指定在 mainDex 中包含的類。通過配置 gradle 文件,指定 gradle 打包過程中,執行 dex 生成時的 keep 文件追加。具體實施是創建一個新的 task,使用 finalizedBy 來指定在 create**MainDexClassList 任務之后執行。另外還需要指定 dx 執行時,添加 —minimal-main-dex 選項,來使 maindex 最小化。
如何判斷 App 啟動過程中哪些類是需要加載的呢?
通過使用類加載 ClassLoader 中,其提供了方法 findLoadedClass。這個方法的作用是用來判斷某個類是否被加載,所以文章中使用的技巧就是通過讀在 second dex files 中的類,來判斷主 dex 是否加載到。若是加載到,則我們就需要將這個類添加至 main dex 來提高 App 的啟動速度。
解決與建議
出現 65k 的問題時候,通過其他方式(重構、優化第三方 SDK的使用)來盡量避免使用 Multidex;若是不可避免地使用,需要對 Multidex 的方式進行優化來使用,來盡量提高我們 App 的啟動速度。
延遲加載
對純 java 文件,可以將其單獨打成一個 dex,利用 Multidex 加載的原理,在當我們使用到相應 java 文件的時候,再加載這個 dex,來執行相應代碼的調用。(方案有些不成熟,不支持涉及到資源文件的情況。)
其他
1. 工具 ClassShark
在評論區,提到的一個軟件 android-classyshark ,可以幫我們更加容易分析 APK、dex、jar 中的使用內容,(不再通過 dex2jar, jd-gui等工具來查看)能夠對 apk 中的內容一目了然, 功能非常強大。
在 Android Studio 2.2 之后的版本,其已經支持了對 apk 的分析,可以直接點擊進行查看。
2. dex2oat 與 dexopt
評論中關于 5.0及以上不受影響的討論,主要原因是因為 5.0 采用了 ART 的編譯方式,其是在 app 安裝的時候執行的,期間對 dex 文件采用了 dex2oat 的執行過程,來對 dex 文件進行優化。而 5.0 之前的設備是沒有這一步,其采用的 dexopt 的過程,并處理的是單個 dex 文件,這樣也會影響了 multidex 的啟動速度,但是這個是每次打開 app 都會進行的,并不是安裝時執行的。
作者的關注點是在每次 App 打開的過程中, Multidex 帶來的影響,所以這個討論在這里并不是與主題太多相關,但是我們還是又必要了解一下的。
參考資料
來自:http://alighters.com/blog/2016/11/01/multidex-problems/