1.問題顯示:
舊版編譯時出現:
Conversion to Dalvik format failed:
Unable to execute dex:method ID not in [0,0xffffff]:65536
新版編譯出現:
trouble writing output:
Too many field references :xxxx;max is 65536
2.原因:
android Dalvik 執行的由class編譯後的.dex檔案檔案規定了單個.dex 檔案最多能引用65536個方法,此問題描述為64K(65536/1024),或者65K(65536/1000),導緻的編譯錯誤提示
3.處理方式:
1. 盡量避免,遏制在搖籃中(畢竟分包是會影響性能的)
dex檔案的來字所有的class檔案,包含自身的方法,還有系統自帶的方法和第三方開源庫,盡可能的去減少不用的函數,不要為了小功能而引入大架構,小功能可以自己去實作,或者在開源庫中提取需要的方法,這也是我們需要解讀開源的一方面,提取所需,避免大炮打蒼蠅,方法盡量複用
2.使用Progurad 混淆來去掉無用的代碼,在Release版本中是能ProGuard
3.分包處理
當項目過大無可避免的時候,隻能做手術了,把dex檔案分成多個包來處理,每個包小于64方法
通過使用系統自帶的MulitDex來分包使能分包方式,
1.首先引入它的庫和其他第三方庫一樣添加
compile 'com.android.support:multidex:1.0.1'
2. 使能 multidex 的支援
defaultConfig{
minSdkVersion 18
targetSdkVersion 23
.........
//使能 multidex 的支援
multiDexEnabled true
}
3.在Application中的attachBaseContext方法中方法中初始
如果沒有定義Application,則定義一個繼承MultiDexApplicaon的類,重寫onCreate,調用下父類的該方法即可
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this)
}
最後注意:
添加了分包處理可能出現的問題:
1.因為多個dex,安裝可能導緻ANR
2.4.0之前的版本可能出現啟動失敗(不過現在該系統使用的比例很小了)
3.大額的記憶體申請配置設定時可能出現crash,因為加載堆記憶體的大小被系統寫死了,android 2.3 以下3M,2.3 5M,4.0 16,5.0由于是ART虛拟機不考慮該問題
4.分包後出現,主從dex檔案包(一個主dex,1個或多個從dex),應用啟動所需要的類必須放在主dex包中不然會出現NoClassDefFoundError錯誤,雖然大多時候,不需要關系,系統會自動幫我們把需要的類添加到主dex包中,但是對于第三依賴庫需要還需要依賴其他的庫的話,比如反射用的類,或者NDK代碼用的類,如果在啟動就需要用到那麼就需要放到主包中
5.編譯建構打包時因為要計算方法,分包處理等,是以很慢,
處理方式
調試時在建構時選擇5.0以上系統建構,因為該系統是ART虛拟機,直接生成一個oat檔案,而不是多個dex合并加載,釋出版時 改為支援的最低版本
android{
productFlavors{
dev{
minSdkVersion 21
}
prod{
minSdkVersion 14//app實際的minSdkVersion
}
}
}