multidex解决方法数越界

Android单个dex文件所能包含的最大方法数是65536,这个包括Android FrameWork、依赖jar包以及应用本身的所有方法。当应用的方法数达到65536之后,编译出现问题。

UNEXPECTED TOP-LEVEL EXCEPTION:  
java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536  
at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501)  
at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:282)  
at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:490)  
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167)  
at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)  
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439)  
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287)  
at com.android.dx.command.dexer.Main.run(Main.java:230)  
at com.android.dx.command.dexer.Main.main(Main.java:199)  
at com.android.dx.command.Main.main(Main.java:103) 
还有一种情况方法数没有达到65536,编译器正常编译完成,但是在低应用版本手机安装时也会报错。程序在安装时会优化dex文件,在优化的过程中会有一个固定的大小的缓冲区来存储应用中的所有方法的信息,这个缓冲区是LinearAlloc。LinearAlloc在新版本的系统中是8m或者16m,在android2.2、2.3只有5m.当安装的apk方法数较多时,尽管没有达到65536的上限,但是它的存储空间可能超出5m,进而导致安装失败。

如何解决这个问题。

首先要删除无用的代码合第三方库,但不一定会起作用。有人提到采用插件化来动态加载部分dex,悲哀啊dex拆分成多个dex,或者多个dex,这种方式一定程度上解决了方法数的问题,但是动态加载apk的技术是比较重量级的技术方案,而且兼容性也有很多问题,不推荐。

2014年Google提出了multidex解决方案。在android5.0之前,需要导入androdi-support-multidex.jar包,5.0之后默认支持了。Multidex方案主要针对的是Android Studio 和Gradle编译环境。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    
    defaultConfig {
        applicationId "com.custom.myapplication"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        //enable multidex support
        multiDexEnabled true

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
   compile 'com.android.support:appcompat-v7:25.2.0'
    testCompile ‘junit:junit:4.12'
	//当前版本低于5.0需要单独导入androdi-support-multidex.jar,这个版本不需要。
}

经过上面的过程还需要在代码中添加支持multidex功能,有三种方案都比较简单。

<application
        android:allowBackup="true"
        android:name="android.support.multidex.MultiDexApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme=“@style/AppTheme">
	……
          </application>

2.让应用的Application继承MultiDexApplication

public class MainApplication extends MultiDexApplication {
    ......
}

同时要把Manifest的application的名字改为MainApplication

<application
        android:allowBackup="true"
        android:name=".MainApplication"
        android:icon=“@mipmap/ic_launcher"
	……
     </application>

3.不想Application继承MultiDexApplication,可以重写Application的attachBaseContext方法,该方法会比Application的onCreate方法先执行。

public class MainApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值