Android-Cannot merge new index 66195 into a non-jumbo instruction的解決的方法

轉載請註明來源:http://blog.csdn.net/goldenfish1919/article/details/33729679html

用eclispe打包的時候報錯:android

[2014-06-23 13:44:35 - Dex Loader] Unable to execute dex: Cannot merge new index 66195 into a non-jumbo instruction!
[2014-06-23 13:44:35 - tao_apad_2.0] Conversion to Dalvik format failed: Unable to execute dex: Cannot merge new index 66195 into a non-jumbo instruction!
app

參考:http://www.cnblogs.com/frydsh/archive/2013/02/20/2918969.html eclipse

最新的ADT和SDK Tool在將jar轉化成dex的時候,可能會合並類的代碼,這將致使巨大的類;類中的每一個方法都分配有一個id,字節碼中以id標識和調用方法;早期的Dalvik VM內部使用short類型變量來標識方法的id,最大值限制在65535;綜合上述因素,代碼在安裝的時候,不能經過驗證,因此安裝失敗。
最新的Android可能已經攻克了這個問題,但是更早的Android版本號可能仍然存在此問題。
所以,由於大量遺留機器的存在,這個問題是不能完全解決的,一個暫時的解決方式是:刪掉沒有實際使用的代碼,或者使用ProGuard處理代碼(可以減少代碼體積)。
一個不幸的推論是:隨着一個軟件功能的添加,代碼的膨脹,APK包終將超出可以處理的範圍,或許就是8M(指APK包裏面的classes.dex).ide

參考:https://code.google.com/p/android/issues/detail?id=40409ui

While the Dalvik team works on a fix, I'm going to allow disabling of the new dex merger features. Builds will be slower (actually back like they were before) but they'll work at least. We were looking at a 21.0.1 release so I'm going to do this now and make sure this gets in.
this

而後,改動project.properties,加入一行:dex.disable.merger=true,竟然可以了。google

文中還有,也是猜的,沒有依據:spa

@18: i think you're confused. there are probably multiple bugs. as i explained in comment 7, the original error is caused by out-of-order annotations. the number of annotations isn't relevant to that bug;all that matters is whether the method indexes they refer to happen to come out in order or not when the merge basically appends them without sorting. (you are though correct that the annotations problem has nothing to do with jumbo mode --- it's the merge step that's the problem.).net

looking at libdex, the reason for your new error is a bit more obscure. it seems to mean that there are references to more than one class in a class_data_item. my assumption is that that means thatone of the fields or methods referred to in the class_data_item doesn't belong to the class we're supposedly defining.i'm afraid i don't know enough about the merge process to know how/why that might happen.

咱們這個問題的解決辦法大概是:

Ufnortunately method call is encoded with a method_id being a short int (so only 65535 different methods), unlike const string access.

So, to summarize, even though the .dex specs allows more than 65535 classes and methods, the vm doesn't support large number of classes/methods, there wasn't any explicit error message.

一個vm最多僅僅能有65536個方法!

dex.force.jumbo是幹嗎的?

To my knowledge, dex.force.jumbo activates the const-string-jumbo opcode which allows to refer to static strings when you have more than 65k strings in your dex file.

假設超過了65k個字符串,啓用dex.force.jumbo這個參數才幹夠引用到所有的字符串。

usually, dx will use the shortest instruction it can. this can make merging impossible if an instruction would need to be widened to fit more bits of string index (or whatever). dex.force.jumbo says "always use the wide form, even if you don't need to", to improve the chances of being able to merge later.

dex.disable.merger的官方解釋參考:http://blog.toolib.net/tools/sdk/eclipse-adt.html:

Added a flag to disable dex merging to deal with cases where merging could generate a broken dex file. If this happens to your project, add the following setting to your project.properties file: dex.disable.merger=true。This setting causes the build system to revert to the older, slower dex processing that does not pre-dex libraries.

也就是說merge可能會出問題,詳細啥問題,沒說,很是操蛋!

昨天還試驗出了一種方法,在project.properties文件里加入如下兩個選項也是可以的:

manifestmerger.enabled=true
dex.force.jumbo=true

咱們的project是因爲引入了一個libproject致使的這個錯誤,所以啓用了manifest merge,而後設置dex.force.jumbo竟然也可以,詳細緣由有待於進一步查明。

關於 manifestmerger.enabled,參考http://stackoverflow.com/questions/10976635/using-the-new-manifestmerger-property-in-android:

Automatic merging of library project manifest files into the including project's manifest. Enable with the manifestmerger.enabled property.

If you want to merge android library project manifest and your current project manifest, you can add manifestmerger.enabled=true in your project.properties file where you referred your library project. But, you should be confirmed some point like ADT version, Also Minimum and target SDK should be same as library project.

所以,這樣的方式是有侷限性的,Minimum和target SDK需要一樣才幹夠。 

相關文章
相關標籤/搜索