如何解決Android65536限制問題

作為一個Android程序員,當你遇見這個錯誤的時候,

Unable to execute dex: method ID not in[0, 0xffff]: 65536。

恭喜你。這說明你的app版本已經迭代的幾個版本了。至少在廣大的用戶心中有那么一席之地。那么這個問題是如何出現的呢?下面我為大家介紹一下,這個問題出現的原因,已經我是怎么解決的。


問題出現原因:在Android系統中,一個App的所有代碼都在一個Dex文件里面。Dex是一個類似Jar的存儲了多有Java編譯字節碼的歸檔文件。因為Android系統使用Dalvik虛擬機,所以需要把使用Java Compiler編譯之后的class文件轉換成Dalvik能夠執行的class文件。這里需要強調的是,Dex和Jar一樣是一個歸檔文件,里面仍然是Java代碼對應的字節碼文件。當Android系統啟動一個應用的時候,有一步是對Dex進行優化,這個過程有一個專門的工具來處理,叫DexOpt。DexOpt的執行過程是在第一次加載Dex文件的時候執行的。這個過程會生成一個ODEX文件,即Optimised Dex。執行ODex的效率會比直接執行Dex文件的效率要高很多。但是在早期的Android系統中,DexOpt會把每一個類的方法id檢索起來,存在一個鏈表結構里面。但是這個鏈表的長度是用一個short類型來保存的,導致了方法id的數目不能夠超過65536個。當一個項目足夠大的時候,顯然這個方法數的上限是不夠的。盡管在新版本的Android系統中,DexOpt修復了這個問題,但是我們仍然需要對低版本的Android系統做兼容.

問題的解決方式:下面說一下我的解決方式,本人使用的是Android Studio工具,首先介紹Studio的解決方式吧,


Android Studio:

1.自定義的MyApplication繼承MultiDexApplication,在MyApplication中重寫attachBaseContext方法,在attachBaseContext方法內部調用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

? ? ? ? ? ? ? ? ?}

}

接下來請運行項目,如果編譯成功,那么項目就可以運行了,但是還是沒有突破65536的限制。如果還不能運行,出現com.android.dex.DexException:MultipledexfilesdefineL{package}/BuildConfig;錯誤,檢查主工程與依賴library工程是否含有重復的support.jar或者其他jar包,我的項目中就是重復引用導致,編譯不通過,我將重復依賴的jar包刪除,再次運行。通過編譯,下面提出幾種解決方案供大家使用:

解決方案:

1. 修改library工程包名

2. 刪除重復jar包

3.手工添加lib包,增加如下配置

dependencies{

compilefileTree(dir:'libs',include:['*.jar'])

compileproject(':lib-project-module')


Eclipse:

1.ant環境配置

下載地址:http://ant.apache.org/bindownload.cgi ,下載apache-ant-1.9.4-bin.zip包.解壓到任意英文目錄.然后配置環境變量,創建變量名為ANT_HOME,值為ant文件對應的路徑,比如我的是ANT_HOME = D:\android\apache-ant-1.9.4-bin。然后在Path變量的值中追加%ANT_HOME%/bin;%ANT_HOME%/lib。這樣ant環境變量就配置好了。

2.拷貝文件

接下來就是拷貝文件custom_rules.xml和pathtool.jar到我們項目的根目錄下,這兩個文件在github上面有https://github.com/mmin18/Dex65536

3.寫項目

然后在你的 Application 方法的onCreate方法里面添加 dexTool(); 方法體在https://github.com/mmin18/Dex65536里面也有.

4.更新工程

打開命令窗口,定位到sdk的tools目錄,輸入命令Android?update project -p + 工程目錄.

如果有依賴庫,每個依賴庫都需要這樣重復一遍.

5.運行程序

最后就是運行程序了. 定位到工程目錄. 輸入命令 : ant clean debug install run

這只是debug運行的。

問題:

1 .如果遇到錯誤: [javac] (請使用 -source 7 或更高版本以啟用 diamond 運算符),則需要編譯%ANDROID_HOME%\ant\build.xml修改下面屬性:

從 1.5 改到 1.7即可。

2.如果引用第三方lib工程,則要進入對那個工程目錄頁執行一遍 update project

update project會在工程目錄下生成 build.xml, local.properties, progard-project.txt 文件;

使用 ant debug 可以編譯 debug 版本的apk文件了。

如果遇到錯誤:ant\build.xml:694: null returned: 1 就關閉eclipse 然后用 ant clean, 在 ant debug 解決;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容