安卓解決java.lang.NoClassDefFoundError錯誤(這里實際上是隱式的65536錯誤)的一種方案

前段時間在開發(fā)一個RN項目時而钞,我是負責安卓原生端組件的開發(fā)冰更,由于集成了大量的第三方sdk裕膀,項目編譯的時候正常辑鲤,但是運行時卻出現(xiàn)了java.lang.NoClassDefFoundError這個錯誤,并且在不同的安卓版本手機運行表現(xiàn)形式都不一樣喷屋,在安卓版本5.0以下的手機運行都會報這個錯琳拨,在5.0及以上的手機運行就正常,不會報錯屯曹,這就讓我非常郁悶了狱庇。最后查找了大量的網(wǎng)上資料才發(fā)現(xiàn)是安卓打包生成Dex 文件方法數(shù)超過了最大值65536的上限引起的,這個時候打包時應該出現(xiàn)下面這個錯誤:

    UNEXPECTED TOP-LEVEL EXCEPTION:  
    java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536  
    at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501)  
    at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:282)  
    at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:490)  
    at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167)  
    at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)  
    at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439)  
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287)  
    at com.android.dx.command.dexer.Main.run(Main.java:230)  
    at com.android.dx.command.dexer.Main.main(Main.java:199)  
    at com.android.dx.command.Main.main(Main.java:103)

目前已發(fā)現(xiàn)的兩種隱式報錯

但是項目并沒有預期的出現(xiàn)這個錯誤是牢,實際報錯為java.lang.NoClassDefFoundError僵井,意思就是找不到某個類,報錯信息也沒有看到65536關鍵字(開發(fā)中還發(fā)現(xiàn)另一種隱式報錯java.lang.VerifyError驳棱,也是由于65536上限引起的),這種隱式報錯導致我解決問題的時候走了很多彎路农曲,后來查找大量的資料才發(fā)現(xiàn)安卓Dex文件方法數(shù)超過了65536的上限(這種隱式報錯真讓人很頭疼)社搅。

關于65536限制

在Android系統(tǒng)中,一個App的所有代碼都在一個Dex文件里面乳规。Dex是一個類似Jar的存儲了多有Java編譯字節(jié)碼的歸檔文件形葬。因為android系統(tǒng)使用Dalvik虛擬機,所以需要把使用Java Compiler編譯之后的class文件轉換成Dalvik能夠執(zhí)行的class文件暮的。這里需要強調的是笙以,Dex和Jar一樣是一個歸檔文件,里面仍然是Java代碼對應的字節(jié)碼文件冻辩。當Android系統(tǒng)啟動一個應用的時候猖腕,有一步是對Dex進行優(yōu)化拆祈,這個過程有一個專門的工具來處理,叫DexOpt倘感。DexOpt的執(zhí)行過程是在第一次加載Dex文件的時候執(zhí)行的放坏。這個過程會生成一個ODEX文件,即Optimised Dex老玛。執(zhí)行ODex的效率會比直接執(zhí)行Dex文件的效率要高很多淤年。但是在早期的Android系統(tǒng)中,DexOpt有一個問題蜡豹,也就是這篇文章想要說明并解決的問題麸粮。DexOpt會把每一個類的方法id檢索起來,存在一個鏈表結構里面镜廉。但是這個鏈表的長度是用一個short類型來保存的弄诲,導致了方法id的數(shù)目不能夠超過65536個。當一個項目足夠大的時候桨吊,顯然這個方法數(shù)的上限是不夠的威根,所以最終就會報java.lang.NoClassDefFoundError。

解決方案:

1视乐、修改build.gradle配置:
defaultConfig {
        ...
        multiDexEnabled true
 }
dependencies {
  compile 'com.android.support:multidex:1.0.1'
}
2洛搀、根據(jù)是否要替換 Application類,執(zhí)行以下操作之一:

如果您沒有重寫 Application類佑淀,請編輯清單文件留美,按如下方式設置<application>標記中的android:name:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
            android:name="android.support.multidex.MultiDexApplication" >
        ...
    </application>
</manifest>

如果您重寫了 Application類,請按如下方式對其進行更改以繼承MultiDexApplication(如果可能):

public class MyApplication extends MultiDexApplication { ... }

或者伸刃,如果您重寫了 Application類谎砾,但無法繼承基本類,則可以改為重寫 attachBaseContext()方法并調用MultiDex.install(this)

public class MyApplication extends SomeOtherApplication {
  @Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(context);
     Multidex.install(this);
  }
}

參考資料:https://developer.android.com/studio/build/multidex.html#mdex-gradle

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末捧颅,一起剝皮案震驚了整個濱河市景图,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碉哑,老刑警劉巖挚币,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扣典,居然都是意外死亡妆毕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門贮尖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笛粘,“玉大人,你說我怎么就攤上這事⌒角埃” “怎么了润努?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長序六。 經(jīng)常有香客問我任连,道長,這世上最難降的妖魔是什么例诀? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任随抠,我火速辦了婚禮,結果婚禮上繁涂,老公的妹妹穿的比我還像新娘拱她。我一直安慰自己,他們只是感情好扔罪,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布秉沼。 她就那樣靜靜地躺著,像睡著了一般矿酵。 火紅的嫁衣襯著肌膚如雪唬复。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天全肮,我揣著相機與錄音敞咧,去河邊找鬼。 笑死辜腺,一個胖子當著我的面吹牛休建,可吹牛的內容都是我干的。 我是一名探鬼主播评疗,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼测砂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了百匆?” 一聲冷哼從身側響起砌些,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎加匈,沒想到半個月后寄症,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡矩动,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了释漆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悲没。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出示姿,到底是詐尸還是另有隱情甜橱,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布栈戳,位于F島的核電站岂傲,受9級特大地震影響,放射性物質發(fā)生泄漏子檀。R本人自食惡果不足惜镊掖,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望褂痰。 院中可真熱鬧亩进,春花似錦、人聲如沸缩歪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匪蝙。三九已至主籍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逛球,已是汗流浹背千元。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留需忿,地道東北人诅炉。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像屋厘,于是被迫代替她去往敵國和親涕烧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容