Too many methods in main-dex 是什么問(wèn)題没咙?

背景:

剛剛通過(guò)MultiDex 解決了Android 65535 的坑,怎么又出現(xiàn)了這個(gè)問(wèn)題以蕴? MultiDex 是官方的解決方案難道還有問(wèn)題糙麦?

先來(lái)說(shuō)下MultiDex 是怎么回事

分兩步:

1.修改gradle腳本來(lái)產(chǎn)生多dex。

2.修改manifest 使用MulitDexApplication丛肮。

步驟1.在gradle腳本里寫(xiě)上:

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. manifest聲明修改為MultiDexApplication

如果有自己的Application赡磅,繼承MulitDexApplication。如果當(dāng)前代碼已經(jīng)繼承自其它Application沒(méi)辦法修改那也行宝与,就重寫(xiě) Application的attachBaseContext()這個(gè)方法焚廊。

@Override

protected void attachBaseContext(Context base) {

super.attachBaseContext(base);

MultiDex.install(this);

}

run一下冶匹,可以了!但是dex過(guò)程好像變慢了咆瘟。嚼隘。。

文檔還寫(xiě)明了multiDex support lib 的局限袒餐。瞄一下是什么:

1.在應(yīng)用安裝到手機(jī)上的時(shí)候dex文件的安裝是復(fù)雜的(complex)有可能會(huì)因?yàn)榈诙€(gè)dex文件太大導(dǎo)致ANR嗓蘑。請(qǐng)用proguard優(yōu)化你的代碼。呵呵

2.使用了mulitDex的App有可能在4.0(api level 14)以前的機(jī)器上無(wú)法啟動(dòng)匿乃,因?yàn)镈alvik linearAlloc bug(Issue 22586) 。請(qǐng)多多測(cè)試自祈多福豌汇。用proguard優(yōu)化你的代碼將減少該bug幾率幢炸。呵呵

3.使用了mulitDex的App在runtime期間有可能因?yàn)镈alvik linearAlloc limit (Issue 78035) Crash。該內(nèi)存分配限制在 4.0版本被增大拒贱,但是5.0以下的機(jī)器上的Apps依然會(huì)存在這個(gè)限制宛徊。

4.主dex被dalvik虛擬機(jī)執(zhí)行時(shí)候,哪些類(lèi)必須在主dex文件里面這個(gè)問(wèn)題比較復(fù)雜逻澳。build tools 可以搞定這個(gè)問(wèn)題闸天。但是如果你代碼存在反射和native的調(diào)用也不保證100%正確。呵呵

感覺(jué)這就是個(gè)坑啊斜做。補(bǔ)丁方案又引入一些問(wèn)題苞氮。但是插件化方案要求對(duì)現(xiàn)有代碼有比較大的改動(dòng),代價(jià)太大瓤逼,而且動(dòng)態(tài)化加載框架意味著維護(hù)成本更高笼吟,會(huì)有更多潛在bug。所以先測(cè)試霸旗,遇到有問(wèn)題的版本再解決贷帮。

4.0 系統(tǒng) ANR 了 ?

問(wèn)題又來(lái)了诱告!這次不僅僅是2.3 的機(jī)型撵枢!還有一些中檔配置的4.x系統(tǒng)的機(jī)型。問(wèn)題現(xiàn)象是:第一次安裝后精居,點(diǎn)擊圖標(biāo)锄禽,1s,2s靴姿,3s... 程序沒(méi)有任何反應(yīng)就好像你沒(méi)點(diǎn)圖標(biāo)一樣沟绪。

5s過(guò)去。空猜。绽慈。程序ANR!

其實(shí)不僅僅總悟君的App存在這個(gè)問(wèn)題恨旱,其他很多App也存在首次安裝運(yùn)行后幾秒都無(wú)任何響應(yīng)的現(xiàn)象或者最后ANR了。唯一的例外是美團(tuán)App坝疼,點(diǎn)擊圖標(biāo)立馬就出現(xiàn)界面搜贤。唉要不就算啦?反正就一次钝凶。仪芒。。不行耕陷,這可是產(chǎn)品給用戶(hù)的第一印象啊太重要了掂名,而且美團(tuán)搞得定就說(shuō)明這問(wèn)題有解決方案。

ANR了是不是局限1描述的現(xiàn)象哟沫?饺蔑?不過(guò)也不重要...因?yàn)镚oogle只是告訴你說(shuō)第二個(gè)dex太大了導(dǎo)致的。并沒(méi)有進(jìn)一步解釋根本原因嗜诀。怎么辦猾警?Google一發(fā)?搜索點(diǎn)擊圖標(biāo) 然后ANR隆敢?怎么可能有解決方案嘛发皿。ANR就意味著UI線(xiàn)程被阻塞了,老老實(shí)實(shí)查看log吧拂蝎。

adb logcat -v time > log.txt

于是發(fā)現(xiàn) 是 install dex + dexopt 時(shí)間太長(zhǎng)穴墅!

梳理一下流程:

安裝完app點(diǎn)擊圖標(biāo)之后,系統(tǒng)木有發(fā)現(xiàn)對(duì)應(yīng)的process温自,于是從該apk抽取classes.dex(主dex) 加載封救,觸發(fā) 一次dexopt。

App 的laucherActivity準(zhǔn)備啟動(dòng) 捣作,觸發(fā)Application啟動(dòng)誉结,

Application的 onattach()方法調(diào)用,這時(shí)候MultiDex.install()調(diào)用券躁,classes2.dex 被install惩坑,再次觸發(fā)dexopt。

然后Applicaition onCreate()執(zhí)行也拜。

然后 launcher Activity真的起來(lái)了以舒。

這些必須在5s內(nèi)完成不然就ANR給你看!

有點(diǎn)棘手慢哈。首先主dex是無(wú)論如何都繞不過(guò)加載和dexopt的蔓钟。如果主dex比較小的話(huà)可以節(jié)省時(shí)間。主dex小就意味著后面的dex大啊卵贱,MultiDex.install()是在主線(xiàn)程里做的滥沫,總時(shí)間又沒(méi)有實(shí)質(zhì)性改變侣集。install() 能不能放到線(xiàn)程里做啊兰绣?貌似不行世分。。缀辩。如果異步化臭埋,什么時(shí)候install完成都不知道。這時(shí)候如果進(jìn)程需要seconday.dex里的classes信息不就悲勍涡瓢阴?主dex越小這個(gè)錯(cuò)誤幾率就越大。要悲劇啊總悟君健无。

淡定荣恐,這次Google搜索MultiDex.install 。于是總悟君發(fā)現(xiàn)了美團(tuán)多dex拆包方案睬涧。 讀完之后感覺(jué)看到勝利曙光。美團(tuán)的主要思路是:精簡(jiǎn)主dex+異步加載secondary.dex 旗唁。對(duì)異步化執(zhí)行速度的不確定性畦浓,他們的解決方案是重寫(xiě)Instrumentation execStartActivity 方法,hook跳轉(zhuǎn)Activity的總?cè)肟谧雠袛嗉煲撸绻?dāng)前secondary.dex 還沒(méi)有加載完成讶请,就彈一個(gè)loading Activity等待加載完成,如果已經(jīng)加載完成那最好不過(guò)了屎媳。不錯(cuò)夺溢,RTFSC果然是王道。 可以試一試烛谊。

但是有幾個(gè)問(wèn)題需要解決:

1.分析主dex需要的classes這個(gè)腳本比較難寫(xiě)风响。。丹禀。Google文檔說(shuō)過(guò)這個(gè)問(wèn)題比較復(fù)雜状勤, 而且buildTools 不是已經(jīng)幫我們搞定了嗎?去瞄一下主dex的大兴帷:8M 以及secondary.dex 3M 持搜。 它是如何工作的?文檔說(shuō)dx的時(shí)候焙矛,先依據(jù)manifest里注冊(cè)的組件生成一個(gè) main-list葫盼,然后把這list里的classes所依賴(lài)的classes找出來(lái),把他們打成classes.dex就是主dex村斟。剩下的classes都放clsses2.dex(如果使用參數(shù)限制dex大小的話(huà)可能會(huì)有classe3.ex 等等) 贫导。主dex至少含有main-list 的classes + 直接依賴(lài)classes 抛猫,使用mini-main-list參數(shù)可以?xún)H僅包含剛才說(shuō)的classes。

關(guān)于寫(xiě)分析腳本的思路是:直接使用mini-main-list參數(shù)獲取build目錄下的main-list文件脱盲,這樣manifest聲明的類(lèi)和他們的直接依賴(lài)類(lèi)搞定的了邑滨,那后者的直接依賴(lài)類(lèi)怎么解?這些在dvk runtime也是必須的classes钱反。一個(gè)思路是解析class文件獲得該class的依賴(lài)類(lèi)掖看。還一個(gè)思路是自己使用Dexclassloader 加載dex,然后hook getClass()方法面哥,調(diào)用一次就記錄一個(gè)哎壳。都挺折騰的。

2.由于歷史原因尚卫,總悟君在維護(hù)的App的manifest注冊(cè)的組件的那些類(lèi)归榕,承載業(yè)務(wù)太多,依賴(lài)很多三方j(luò)ar吱涉,導(dǎo)致直接依賴(lài)類(lèi)非常多刹泄,而且短時(shí)間內(nèi)無(wú)法梳理精簡(jiǎn),沒(méi)辦法mini化主dex怎爵。

3.Application的啟動(dòng)入口太多特石。Appication初始化未必是由launcher Activity的啟動(dòng)觸發(fā),還有可能是因?yàn)镾ervice 鳖链,Receiver 姆蘸,ContentProvider 的啟動(dòng)。 靠攔截重寫(xiě)Instrumentation execStartActivity 解決不了問(wèn)題芙委。要為 Service 逞敷,Receiver ,ContentProvider 分別寫(xiě)基類(lèi)灌侣,然后在oncreate()里判斷是否要異步加載secondary.dex推捐。如果需要,彈出Loading Acitvity侧啼?用戶(hù)看到這個(gè)會(huì)感覺(jué)比較怪異玖姑。

結(jié)合自身App的實(shí)際情況來(lái)看美團(tuán)的拆包方案雖然很美好然但是不能照搬啊。果然不能愉快地回家看動(dòng)漫了慨菱。

相關(guān)資料

Android拆分與加載Dex的多種方案對(duì)比

美團(tuán)Android DEX自動(dòng)拆包及動(dòng)態(tài)加載簡(jiǎn)介

Android傻瓜式分包插件及一些坑

MultiDex中出現(xiàn)的main dex capacity exceeded解決之道

Android Dex分包之旅

dex分包變形記









...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末焰络,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子符喝,更是在濱河造成了極大的恐慌闪彼,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異畏腕,居然都是意外死亡缴川,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)描馅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)把夸,“玉大人,你說(shuō)我怎么就攤上這事铭污×等眨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵嘹狞,是天一觀的道長(zhǎng)岂膳。 經(jīng)常有香客問(wèn)我,道長(zhǎng)磅网,這世上最難降的妖魔是什么谈截? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮涧偷,結(jié)果婚禮上簸喂,老公的妹妹穿的比我還像新娘。我一直安慰自己燎潮,他們只是感情好喻鳄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著跟啤,像睡著了一般诽表。 火紅的嫁衣襯著肌膚如雪唉锌。 梳的紋絲不亂的頭發(fā)上隅肥,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音袄简,去河邊找鬼腥放。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绿语,可吹牛的內(nèi)容都是我干的秃症。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吕粹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼种柑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起匹耕,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤聚请,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驶赏,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炸卑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了煤傍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盖文。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蚯姆,靈堂內(nèi)的尸體忽然破棺而出五续,到底是詐尸還是另有隱情,我是刑警寧澤蒋失,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布返帕,位于F島的核電站,受9級(jí)特大地震影響篙挽,放射性物質(zhì)發(fā)生泄漏荆萤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一铣卡、第九天 我趴在偏房一處隱蔽的房頂上張望链韭。 院中可真熱鬧,春花似錦煮落、人聲如沸敞峭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)旋讹。三九已至,卻和暖如春轿衔,著一層夾襖步出監(jiān)牢的瞬間沉迹,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工害驹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鞭呕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓宛官,卻偏偏與公主長(zhǎng)得像葫松,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子底洗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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