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
}
}
}