在将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