Dalvik 65K methods limit
你很快就會遇到的,不過放心,multidexing
會幫助你。
什么是Dalvik 65K methods limit?我們知道,我們寫完java code之后,dx tool會把java編譯的class文件再編譯成Dalivik虛擬機能識別的DEX文件,這個文件里最多能夠索引65536個method。關于這個有兩點要注意:
- 這些method是指能夠索引(reference)到的,而不是定義(define)
的。或者說,如果你定義了一個方法,但這個方法并沒有被調用,那么就不算在內。 - 這些method不僅僅是開發人員自己寫的,還包括所有第三方library里面的method。
索引是用一個鏈表結構存儲的,類型是short,short占2字節,16位,2^16=65536,所以,我們總共可以索引65536
個方法,包括自己寫的和引入第三方庫里的。
那么,我們如何能快速知道我們的app里已經有多少個method了呢?
- bash script: dex-method-counts。這個工具可以快速計算,并且提供一個清晰的視圖來閱讀。
- dex.sh by Jake Wharton。這個工具由于采用了遞歸算法,所以耗時比較長。(Jake大神還寫了一篇有趣的分析文章Play Services 5.0 Is A Monolith Abomination,針對Play Services 5.0太大的問題進行了分析,有空時我再翻譯下給各位。雖然Play Services 6.5已經模塊化,更加輕量級了)。
現在,既然我們已經知道了自家app里的method數了,那么如何來處理這種情況呢?(官方做法、減少方法數、分包、插件化、增大可容納的方法數)
- Multidex,官方提供的解決方案(這個jar包最低可以支持到API 4的版本,5.0及以上版本默認支持),這篇文章里有詳細的使用方法,此不贅述(使用Multidex support library)原理:將Multidex作為基本的dex,用它再去管理其他的dex。
-
ProGuardProGuard
可以把code里unnecessary的method移除,壓縮apk,當然還有代碼混淆
的奇效。 - 使用H5文件代替一部分的邏輯代碼。
- 再創建一個DEX File
。把app里可以獨立的模塊或code提取出來,放到一個獨立的dex文件里,你可以使用Custom ClassLoader來加載這些類,然后使用接口
或反射
來調用這些方法。不過,這個過程還是比較麻煩的。 - 插件化: https://github.com/singwhatiwanna/dynamic-load-apk
- 如果使用eclipse,可以在Project.proterty中配置一句話就Ok啦, dex.force.jumbo=true,應該是暫時增大可容納的方法數,也就是說方法在增大,還是會遇到問題,具體不是很了解,請各位大神指教!