隨着5.0的推出,Android也放出了Multidex Support Library來解決問題。
compile 'com.android.support:multidex:1.0.1'
release {
minifyEnabled false
//分包
multiDexEnabled true
proguardFiles getDefaultProguardFile( 'proguard-android.txt'), 'proguard-rules.pro'
}
}
javaMaxHeapSize "4g"
incremental true
}
...
}
protected void attachBaseContext(Context base) {
super.attachBaseContext(base) ;
MultiDex. install(base) ;
}
分包之后就存在一個主的classes.dex,多個副的classes2.dex,classes3.dex…
1 |
collect{variant}MultiDexComponents task |
這個task會讀取項目的AndroidManifest.xml文件里注冊的application、Activity、service、receiver、provider、instrumentation相關類,並將其class文件路徑寫到文件buidl/intermediates/multi-dex/${variant.dirName}/manifest_keep.txt
中
1 |
shrink{variant}MultiDexComponents task |
這個task會調用ProGuard並依據上一步生成的manifest_keep.txt文件內容去壓縮class,剔除沒實用到的class。生成一個精簡的jar包buidl/intermediates/multi-dex/${variant.dirName}/componentClasses.jar
1 |
create{variant}MainDexClassList task |
這個task會依據上一步生成的componentClasses.jar去尋找這里面的各個class文字中依賴的class,比方一個class中有一成員變量X。那么X就是依賴的class,componentClasses.jar中全部的class和依賴的class路徑都會被寫入到文件buidl/intermediates/multi-dex/${variant.dirName}/maindexlist.txt
中,這個文件里的類都會被編譯進主的classes.dex中去。(詳情能夠查看ClassReferenceListBuilder的實現源代碼)
NoClassDefFoundError
Multidex固然是好的,不用再為方法數超過65536而苦惱了。
可是有時往往會帶來意想不到的bug。比方NoClassDefFoundError。之前我就在項目中遇到了這個問題。一啟動程序就crash了,看log是因為某個類找不到引起的。
create{variant}MainDexClassList
這個task完畢之后再去改動maindexlist.txt文件加入丟失的class。