在將ADT和SDK Tool升級到最新(分別是21.1和16.0.1)之后,我的一個工程(相對比較大)在編譯並運行的時候,出現錯誤,Eclipse控制台輸出如下信息:
Unable to execute dex: Cannot merge new index 67208 into a non-jumbo instruction!
Conversion to Dalvik format failed: Unable to execute dex: Cannot merge new index 67208 into a non-jumbo instruction!
很多人在升級ADT和SDK Tool之后,都會遇到這個問題,只是錯誤信息中的數字不同而已。
而且,我還發現一個現象:如果只是編譯,但不生成APK,並不會出錯;其實,從上面的錯誤信息中也可以看出一些線索 --- 它是在將jar文件轉換成dex文件的時候出錯的。
網上給出的解決方案是,將dex.force.jumbo=true添加到project.properties文件中,然后清理工程,並重新編譯。
這個方法可以解決編譯階段問題,但是產生的APK在某些機器上不能安裝(Installation error: INSTALL_FAILED_DEXOPT),針對這個問題的一個可能解釋是:
最新的ADT和SDK Tool在將jar轉化成dex的時候,可能會合並類的代碼,這將導致巨大的類;類中的每一個方法都分配有一個id,字節碼中以id標識和調用方法;早期的Dalvik VM內部使用short類型變量來標識方法的id,最大值限制在65535;綜合上述因素,代碼在安裝的時候,不能通過驗證,所以安裝失敗。
最新的Android可能已經解決了這個問題,但是更早的Android版本可能仍然存在此問題。
因此,由於大量遺留機器的存在,這個問題是不能徹底解決的,一個臨時的解決方案是:刪掉沒有實際使用的代碼,或者使用ProGuard處理代碼(可以減小代碼體積)。
一個不幸的推論是:隨着一個軟件功能的增加,代碼的膨脹,APK包終將超出可以處理的范圍,也許就是8M(指APK包里面的classes.dex).
與此問題相關的兩個討論組是:
https://code.google.com/p/android/issues/detail?id=40409
https://groups.google.com/forum/?fromgroups=#!topic/adt-dev/tuLXN9GkVas