解決Android單個dex檔案不能超過65535個方法問題
一、找坑:谷歌規定單個dex檔案中的方法不能超過65536的限制
我們編寫專案過程中在工程的lib資料夾下引用的第三方外掛jar包太多或者專案過大,編譯執行時就有可能報出com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536錯誤。看到這個錯誤說明你的方法加起來已經超過了65536這個數目。但是谷歌規定單個dex檔案中的方法不能超過65536的限制。
如下圖所示,Android Studio 中的Message顯示了錯誤
這裡是具體的錯誤程式碼:
Error:Execution failed for task ':app:transformClassesWithDexForDebug'. > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
遇到這個坑的時候找了半天的jar包重複,也是一時糊塗,吸取教訓
好了,錯誤已經找到我們來解決問題,坑總是要填的。
二、填坑
有網友說在module的build.gradle檔案中新增依據話就解決了 : multiDexEnabled true
defaultConfig { applicationId "com.xxx.xxx" minSdkVersion 18 targetSdkVersion 25 versionCode 1 versionName "1.0" multiDexEnabled true }
執行編譯後你可能沒發現問題,但是有些情況下APP直接就蹦了,坑還是好多啊
我這裡就跳進來了,竟然報了一堆的錯,如下是錯誤提示的error
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.xxx.xxx/com.xxx.xxx.ui.actmain.MainAct}: java.lang.ClassNotFoundException: Didn't find class "com.xxx.xxx.ui.actmain.MainAct" on path: DexPathList[[zip file "/data/app/com.xiaodongwa.vronline-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.xxx.xxx-2, /vendor/lib, /system/lib]] at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2190) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2313) at android.app.ActivityThread.access$1100(ActivityThread.java:141) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1238) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5336) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.ClassNotFoundException: Didn't find class "com.xxx.xxx.ui.actmain.MainAct" on path: DexPathList[[zip file "/data/app/com.xxx.xxx-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.xxx.xxx-2, /vendor/lib, /system/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:497) at java.lang.ClassLoader.loadClass(ClassLoader.java:457) at android.app.Instrumentation.newActivity(Instrumentation.java:1064) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2181) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2313) at android.app.ActivityThread.access$1100(ActivityThread.java:141) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1238) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5336) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) at dalvik.system.NativeStart.main(Native Method)
看到這一片紅瞬間就崩潰了,還以為就加依據程式碼就夠了,看來不是,一片血海中找到了關鍵部分
ClassNotFoundException: Didn't find class "com.xxx.xxx.ui.actmain.MainAct" on path: DexPathList[[zip file "/data/app/com.xxx.xxx-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.xxx.xxx-2, /vendor/lib, /system/lib]]
在 Caused by:部分發現:Didn't find class "com.xiaodongwa.vronline.ui.actmain.MainAct" on path: DexPathList[[zip file "/data/app/com.xiaodongwa.vronline-2.apk"]
這句關鍵錯誤就是在DexPathList中找不到那個MainAct的類,dex讀起來好熟悉,這不是我們打包以後的.dex檔案的字尾麼,這就涉及到了Android多分包技術MultiDex
OK,繼續填坑
三、詳解多分包技術的
實現多分包技術,我們首先需要使用Android SDK Build Tools 21.1及以上的版本,完成後還需要在dependencies中新增multidex的依賴,記得不要忘記新增上邊提到的那句話
1、multiDexEnabled true
2、新增依賴
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
方案一、讓應用的中自己定義的Application繼承MultiDexApplication
public class MyApplication extends MultiDexApplication{
……
}
切記不要忘記在manifest.xml檔案中修改啟動的Application為自己定義的Application,否則程式會崩潰
方案二、重寫Application 的attachBaseContext方法,這個方法是在onCreate之前執行的
public class MyApplication extends Application{
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
這樣編譯執行程式即可解決問題了
如有錯誤或者問題歡迎指教