Android應用打破65K方法數(shù)限制

近日镜沽,Android Developers在Google+上宣布了新的Multidex支持庫,為方法總數(shù)超過65K的Android應用提供了官方支持桨吊。
如果你是一名幸運的Android應用開發(fā)者威根,正在開發(fā)一個前景廣闊的應用,不斷地加入新功能视乐、添加新的類庫洛搀,那么終有一天,你會不幸遇到這個錯誤:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

這個錯誤是Android應用的方法總數(shù)限制造成的佑淀。Android平臺的Java虛擬機Dalvik在執(zhí)行DEX格式的Java應用程序時留美,使用原生類型short來索引DEX文件中的方法。這意味著單個DEX文件可被引用的方法總數(shù)被限制為65536。通常APK包含一個classes.dex文件独榴,因此Android應用的方法總數(shù)不能超過這個數(shù)量僧叉,這包括Android框架、類庫和你自己開發(fā)的代碼棺榔。
這個問題可以通過將一個DEX文件分拆成多個DEX文件解決瓶堕。Facebook介紹了為Android應用開發(fā)的Dalvik補丁;Android Developers博客介紹了通過自定義類加載過程的方法來解決此問題症歇。但這些方法有些復雜而且并不優(yōu)雅郎笆。
隨著新的MultiDex支持庫發(fā)布,Google正式為解決此問題提供官方支持忘晤。構建超過65K方法數(shù)的應用介紹了如何使用Gradle構建多DEX應用宛蚓。
首先使用Android SDK Manager升級到最新的Android SDK Build Tools和Android Support Library R21。然后進行以下兩步操作:
1.修改Gradle配置文件设塔,啟用MultiDex并包含MultiDex支持:
android { compileSdkVersion 21 buildToolsVersion "21.1.0"defaultConfig { ... minSdkVersion 14 targetSdkVersion 21 ... // Enabling multidex support. multiDexEnabled true}...}dependencies { compile 'com.android.support:multidex:1.0.0' }
2.讓應用支持多DEX文件凄吏。在MultiDexApplication JavaDoc中描述了三種可選方法:
在AndroidManifest.xml的application中聲明android.support.multidex.MultiDexApplication;
如果你已經(jīng)有自己的Application類闰蛔,讓其繼承MultiDexApplication痕钢;
如果你的Application類已經(jīng)繼承自其它類,你不想/能修改它序六,那么可以重寫attachBaseContext()方法:

@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this);}
經(jīng)過以上步驟任连,你的應用已經(jīng)可以實現(xiàn)多個DEX文件了。當應用構建時例诀,構建工具會分析哪些類必須放在第一個DEX文件随抠,哪些類可以放在附加的DEX文件中。當它創(chuàng)建了第一個DEX文件(classes.dex)后繁涂,如果有必要會繼續(xù)創(chuàng)建附加的DEX文件拱她,如classes2.dex, classes3.dex。Multidex的支持類庫將被包含在應用的第一個DEX文件中扔罪,幫助實現(xiàn)對其它DEX文件的訪問秉沼。
文中還介紹了在開發(fā)多DEX應用時,通過設置productFlavors提高開發(fā)效率以及多DEX應用的測試方法步势。
Android 5.0和更高版本使用名為ART的運行時氧猬,它原生支持從APK文件加載多個DEX文件。在應用安裝時坏瘩,它會執(zhí)行預編譯盅抚,掃描classes(..N).dex文件然后將其編譯成單個.oat文件用于執(zhí)行。了解更多關于ART的信息倔矾。
雖然Google解決了應用總方法數(shù)限制的問題妄均,但并不意味著開發(fā)者可以任意擴大項目規(guī)模柱锹。Multidex仍有一些限制:
DEX文件安裝到設備的過程非常復雜,如果第二個DEX文件太大丰包,可能導致應用無響應禁熏。此時應該使用ProGuard減小DEX文件的大小。
由于Dalvik linearAlloc的Bug邑彪,應用可能無法在Android 4.0之前的版本啟動瞧毙,如果你的應用要支持這些版本就要多執(zhí)行測試。
同樣因為Dalvik linearAlloc的限制寄症,如果請求大量內(nèi)存可能導致崩潰宙彪。Dalvik linearAlloc是一個固定大小的緩沖區(qū)。在應用的安裝過程中有巧,系統(tǒng)會運行一個名為dexopt的程序為該應用在當前機型中運行做準備释漆。dexopt使用LinearAlloc來存儲應用的方法信息。Android 2.2和2.3的緩沖區(qū)只有5MB篮迎,Android 4.x提高到了8MB或16MB男图。當方法數(shù)量過多導致超出緩沖區(qū)大小時,會造成dexopt崩潰甜橱。
Multidex構建工具還不支持指定哪些類必須包含在首個DEX文件中逊笆,因此可能會導致某些類庫(例如某個類庫需要從原生代碼訪問Java代碼)無法使用。

避免應用過大渗鬼、方法過多仍然是Android開發(fā)者要注意的問題览露。Mihai Parparita的開源項目dex-method-counts可以用于統(tǒng)計APK中每個包的方法數(shù)量荧琼。
通常開發(fā)者自己的代碼很難達到這樣的方法數(shù)量限制譬胎,但隨著第三方類庫的加入,方法數(shù)就會迅速膨脹命锄。因此選擇合適的類庫對Android開發(fā)者來說尤為重要堰乔。
開發(fā)者應該避免使用Google Guava這樣的類庫,它包含了13000多個方法脐恩。盡量使用專為移動應用設計的Lite/Android版本類庫镐侯,或者使用小類庫替換大類庫,例如用Google-gson替換Jackson JSON驶冒。而對于Google Protocol Buffers這樣的數(shù)據(jù)交換格式苟翻,其標準實現(xiàn)會自動生成大量的方法。采用Square Wire的實現(xiàn)則可以很好地解決此問題骗污。

文章來源:http://www.infoq.com/cn/news/2014/11/android-multidex

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末崇猫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子需忿,更是在濱河造成了極大的恐慌诅炉,老刑警劉巖蜡歹,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涕烧,居然都是意外死亡月而,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門议纯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來父款,“玉大人,你說我怎么就攤上這事瞻凤☆趵欤” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵鲫构,是天一觀的道長浓恶。 經(jīng)常有香客問我,道長结笨,這世上最難降的妖魔是什么包晰? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮炕吸,結(jié)果婚禮上伐憾,老公的妹妹穿的比我還像新娘。我一直安慰自己赫模,他們只是感情好树肃,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瀑罗,像睡著了一般胸嘴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斩祭,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天劣像,我揣著相機與錄音,去河邊找鬼摧玫。 笑死耳奕,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的诬像。 我是一名探鬼主播屋群,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坏挠!你這毒婦竟也來了芍躏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤癞揉,失蹤者是張志新(化名)和其女友劉穎纸肉,沒想到半個月后溺欧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡柏肪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年姐刁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烦味。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡聂使,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谬俄,到底是詐尸還是另有隱情柏靶,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布溃论,位于F島的核電站屎蜓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏钥勋。R本人自食惡果不足惜炬转,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望算灸。 院中可真熱鬧扼劈,春花似錦、人聲如沸菲驴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赊瞬。三九已至先煎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間森逮,已是汗流浹背榨婆。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工磁携, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留褒侧,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓谊迄,卻偏偏與公主長得像闷供,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子统诺,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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