作為一個(gè)Android程序員,當(dāng)你遇見這個(gè)錯(cuò)誤的時(shí)候简肴,
Unable to execute dex: method ID not in[0, 0xffff]: 65536。
恭喜你稠项。這說明你的app版本已經(jīng)迭代的幾個(gè)版本了驾荣。至少在廣大的用戶心中有那么一席之地。那么這個(gè)問題是如何出現(xiàn)的呢帆吻?下面我為大家介紹一下域那,這個(gè)問題出現(xiàn)的原因,已經(jīng)我是怎么解決的。
問題出現(xiàn)原因:在Android系統(tǒng)中次员,一個(gè)App的所有代碼都在一個(gè)Dex文件里面败许。Dex是一個(gè)類似Jar的存儲(chǔ)了多有Java編譯字節(jié)碼的歸檔文件。因?yàn)锳ndroid系統(tǒng)使用Dalvik虛擬機(jī)淑蔚,所以需要把使用Java Compiler編譯之后的class文件轉(zhuǎn)換成Dalvik能夠執(zhí)行的class文件市殷。這里需要強(qiáng)調(diào)的是,Dex和Jar一樣是一個(gè)歸檔文件刹衫,里面仍然是Java代碼對(duì)應(yīng)的字節(jié)碼文件醋寝。當(dāng)Android系統(tǒng)啟動(dòng)一個(gè)應(yīng)用的時(shí)候,有一步是對(duì)Dex進(jìn)行優(yōu)化带迟,這個(gè)過程有一個(gè)專門的工具來處理音羞,叫DexOpt。DexOpt的執(zhí)行過程是在第一次加載Dex文件的時(shí)候執(zhí)行的仓犬。這個(gè)過程會(huì)生成一個(gè)ODEX文件嗅绰,即Optimised Dex。執(zhí)行ODex的效率會(huì)比直接執(zhí)行Dex文件的效率要高很多搀继。但是在早期的Android系統(tǒng)中办陷,DexOpt會(huì)把每一個(gè)類的方法id檢索起來,存在一個(gè)鏈表結(jié)構(gòu)里面律歼。但是這個(gè)鏈表的長(zhǎng)度是用一個(gè)short類型來保存的民镜,導(dǎo)致了方法id的數(shù)目不能夠超過65536個(gè)。當(dāng)一個(gè)項(xiàng)目足夠大的時(shí)候险毁,顯然這個(gè)方法數(shù)的上限是不夠的制圈。盡管在新版本的Android系統(tǒng)中,DexOpt修復(fù)了這個(gè)問題畔况,但是我們?nèi)匀恍枰獙?duì)低版本的Android系統(tǒng)做兼容.
問題的解決方式:下面說一下我的解決方式鲸鹦,本人使用的是Android Studio工具,首先介紹Studio的解決方式吧跷跪,
Android Studio:
1.自定義的MyApplication繼承MultiDexApplication馋嗜,在MyApplication中重寫attachBaseContext方法,在attachBaseContext方法內(nèi)部調(diào)用MultiDex.install(this)方法;
2.Project-->app-->build.gradle文件中吵瞻,在defaultConfig中添加代碼multiDexEnabledtrue true葛菇,在gradle方法中添加
afterEvaluate{
? ? ? ? ? ? ? ? tasks.matching {
? ? ? ? ? ? ? ? ? ? ? ? ? it.name.startsWith('dex')
? ? ? ? ? ? ? ? ?}.each { dx ->
? ? ? ? ? ? ? ? if(dx.additionalParameters ==null) {
? ? ? ? ? ? ? ? ? ? ? ? ? dx.additionalParameters = []
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?dx.additionalParameters +='--multi-dex' ? ? ? ? // enable multidex
? ? ? ? ? ? ? ? ?}
}
接下來請(qǐng)運(yùn)行項(xiàng)目,如果編譯成功橡羞,那么項(xiàng)目就可以運(yùn)行了眯停,但是還是沒有突破65536的限制。如果還不能運(yùn)行卿泽,出現(xiàn)com.android.dex.DexException:MultipledexfilesdefineL{package}/BuildConfig;錯(cuò)誤莺债,檢查主工程與依賴library工程是否含有重復(fù)的support.jar或者其他jar包,我的項(xiàng)目中就是重復(fù)引用導(dǎo)致,編譯不通過齐邦,我將重復(fù)依賴的jar包刪除椎侠,再次運(yùn)行。通過編譯措拇,下面提出幾種解決方案供大家使用:
解決方案:
1. 修改library工程包名
2. 刪除重復(fù)jar包
3.手工添加lib包,增加如下配置
dependencies{
compilefileTree(dir:'libs',include:['*.jar'])
compileproject(':lib-project-module')
Eclipse:
1.ant環(huán)境配置
下載地址:http://ant.apache.org/bindownload.cgi ,下載apache-ant-1.9.4-bin.zip包.解壓到任意英文目錄.然后配置環(huán)境變量肺蔚,創(chuàng)建變量名為ANT_HOME,值為ant文件對(duì)應(yīng)的路徑儡羔,比如我的是ANT_HOME = D:\android\apache-ant-1.9.4-bin宣羊。然后在Path變量的值中追加%ANT_HOME%/bin;%ANT_HOME%/lib。這樣ant環(huán)境變量就配置好了汰蜘。
2.拷貝文件
接下來就是拷貝文件custom_rules.xml和pathtool.jar到我們項(xiàng)目的根目錄下,這兩個(gè)文件在github上面有https://github.com/mmin18/Dex65536仇冯。
3.寫項(xiàng)目
然后在你的 Application 方法的onCreate方法里面添加 dexTool(); 方法體在https://github.com/mmin18/Dex65536里面也有.
4.更新工程
打開命令窗口,定位到sdk的tools目錄,輸入命令Android?update project -p + 工程目錄.
如果有依賴庫,每個(gè)依賴庫都需要這樣重復(fù)一遍.
5.運(yùn)行程序
最后就是運(yùn)行程序了. 定位到工程目錄. 輸入命令 : ant clean debug install run
這只是debug運(yùn)行的。
問題:
1 .如果遇到錯(cuò)誤: [javac] (請(qǐng)使用 -source 7 或更高版本以啟用 diamond 運(yùn)算符)族操,則需要編譯%ANDROID_HOME%\ant\build.xml修改下面屬性:
從 1.5 改到 1.7即可苛坚。
2.如果引用第三方lib工程,則要進(jìn)入對(duì)那個(gè)工程目錄頁執(zhí)行一遍 update project
update project會(huì)在工程目錄下生成 build.xml色难, local.properties, progard-project.txt 文件泼舱;
使用 ant debug 可以編譯 debug 版本的apk文件了。
如果遇到錯(cuò)誤:ant\build.xml:694: null returned: 1 就關(guān)閉eclipse 然后用 ant clean, 在 ant debug 解決枷莉;