一個(gè)詭異的 Android 大坑

編譯 Android 工程的時(shí)候,意外遇到了這樣一個(gè)錯(cuò)誤:

com.android.dex.DexIndexOverflowException: Cannot merge new index 66739 into a non-jumbo instruction!

通過谷歌搜索這個(gè)問題售睹,發(fā)現(xiàn) StackOverflow 上面已經(jīng)有人遇到過相同的問題了:Application too big? Unable to execute dex: Cannot merge new index into a non-jumbo instruction幢痘。

大家給出的解釋是,一個(gè) dex 文件中至多容許存在 64K 個(gè)方法,超過這一限制悯辙,編譯器就會報(bào)錯(cuò)。

至于為什么 Android 中會有這樣一個(gè)詭異的數(shù)目限制迎吵,我猜測是因?yàn)?dalvik 中的某個(gè)計(jì)數(shù)器使用了 short 類型躲撰,因?yàn)?64K 剛好等于 65536。檢索了一番 dalvik 的源碼击费,發(fā)現(xiàn)確實(shí)如此拢蛋,下面是埋下了這個(gè)大坑的代碼:

// dalvik/dx/src/com/android/dx/merge/IndexMap.java
public IndexMap(Dex target, TableOfContents tableOfContents) {
    ...
    public final short[] typeIds;
    public final short[] protoIds;
    public final short[] fieldIds;
    public final short[] methodIds;
    ...
}

從代碼中可以看出,不只是 methodIds 不能超過 65536 個(gè)蔫巩,typeIds谆棱、protoIds 以及 fieldIds 也都是如此。想必 dalvik 的開發(fā)者當(dāng)初寫下這幾行代碼的時(shí)候圆仔,心中是這么考慮的:六萬五千多個(gè)方法還不夠你們用的嗎垃瞧?

開發(fā)者在設(shè)計(jì)新功能或者新協(xié)議的時(shí)候,往往顯得過于保守與短視荧缘。比如皆警,IPv4 的設(shè)計(jì)者們顯然并沒有預(yù)料到我們今天會遭遇 IP 地址耗盡的危機(jī)。

現(xiàn)在截粗,同樣的問題出現(xiàn)在了 Android 開發(fā)者的面前信姓。隨著應(yīng)用程序功能的日益復(fù)雜,源碼的規(guī)模正在逐漸增大绸罗,勢必有一天意推,代碼中方法的數(shù)量終將超出限制。最徹底的解決辦法自然是升級 dalvik 的源代碼珊蟀,把計(jì)數(shù)器的計(jì)數(shù)范圍擴(kuò)大菊值。然而外驱,由于當(dāng)前版本的 dalvik 已經(jīng)廣泛運(yùn)行在了大量的安卓設(shè)備中(全世界安卓設(shè)備的激活數(shù)已經(jīng)超過了 10 億臺),這種毫無向前兼容性的解決辦法顯然不可取腻窒。

那么昵宇,作為開發(fā)者,該怎樣避免這個(gè)問題呢儿子?Android 的官方開發(fā)者網(wǎng)站上面有一篇專門討論這個(gè)主題的文章: Building Apps with Over 65K Methods瓦哎。

總結(jié)來說,有兩種可選方案:

一種辦法是減小程序的規(guī)模柔逼,這可以通過刨除無用代碼以及減少項(xiàng)目的依賴來達(dá)成蒋譬。不過這終究只是權(quán)宜之計(jì),只能拖延時(shí)間愉适,并不能阻止末日的到來犯助。

另一種辦法是把編譯生成的字節(jié)碼文件分割成為兩個(gè)或者更多 dex 文件,以此規(guī)避單個(gè) dex 文件中的方法總數(shù)不得超過 65536 的限制维咸。

要知道剂买,dalvik 強(qiáng)制限定了一個(gè) APK 包中只能包含一個(gè)字節(jié)碼文件。 這篇文章提供了一種有趣的思路腰湾,幫助我們理解為什么分割字節(jié)碼文件是可行的雷恃。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疆股,一起剝皮案震驚了整個(gè)濱河市费坊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旬痹,老刑警劉巖附井,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異两残,居然都是意外死亡永毅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門人弓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沼死,“玉大人,你說我怎么就攤上這事崔赌∫庵” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵健芭,是天一觀的道長县钥。 經(jīng)常有香客問我,道長慈迈,這世上最難降的妖魔是什么若贮? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上谴麦,老公的妹妹穿的比我還像新娘蠢沿。我一直安慰自己,他們只是感情好匾效,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布搏予。 她就那樣靜靜地躺著,像睡著了一般弧轧。 火紅的嫁衣襯著肌膚如雪雪侥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天精绎,我揣著相機(jī)與錄音速缨,去河邊找鬼。 笑死代乃,一個(gè)胖子當(dāng)著我的面吹牛旬牲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播搁吓,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼原茅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了堕仔?” 一聲冷哼從身側(cè)響起擂橘,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摩骨,沒想到半個(gè)月后通贞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恼五,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年昌罩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灾馒。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茎用,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出睬罗,到底是詐尸還是另有隱情轨功,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布傅物,位于F島的核電站夯辖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏董饰。R本人自食惡果不足惜蒿褂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一圆米、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啄栓,春花似錦娄帖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至堪旧,卻和暖如春削葱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淳梦。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工析砸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爆袍。 一個(gè)月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓首繁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親陨囊。 傳聞我的和親對象是個(gè)殘疾皇子弦疮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容