Android开发——解决方法数越界问题

0. 前言

因为单个DEX文件能够包含的最大方法总数为65536,通常APK包含一个DEX文件,因此Android应用的方法总数不能超过这个数量,这包括Android框架、第三方类库和你自己开发的代码。随着第三方类库的加入,方法数就会迅速膨胀。直到遇见下面这个错误:

com.android.dex.DexIndexOverFlowException: method ID not in [0, 0xffff]: 65536

带着这个问题开始这篇文章,转载请注明出处:Android开发——解决方法数越界问题_SEU_Calvin的博客-CSDN博客

1.  引入multidex

2014Google正式提出multidex为解决此问题的官方方案,即使用Gradle构建多DEX应用Android 5.0之前需要引入extras/android/support/multidex/library/libs/android-support-multidex.jar, 5.0以后默认支持了multidex,所以在Bulid Tool21.1以及以上版本配置multidex是一件容易的事情。

1.1    修改Gradle配置文件

android { 
compileSdkVersion 21 
buildToolsVersion "21.1.0"

defaultConfig {
    ...
    minSdkVersion 14
    targetSdkVersion 21
    ...

    // Enabling multidex support
    multiDexEnabled true
}
...
}

并在dependencies中添加multidex的依赖:

dependencies { 
      ...
compile 'com.android.support:multidex:1.0.0' 
} 

1.2    在代码中加入支持multidex的功能

根据MultiDexApplication JavaDoc的建议,共有三种可选方法:

1)在Manifest.xmlapplication节点中声明android:name=android.support.multidex.MultiDexApplication

2)如果你已经有自己的Application类,Application类继承MultiDexApplication

3)如果你不想让你的Application类去继承MultiDexApplication,那么可以选择重写attachBaseContext()方法:

@Override 
protected void attachBaseContext(Context base) {
super.attachBaseContext(base); 
MultiDex.install(this);
}

这样当你的应用方法数超过65K就会生成两个或更多dex文件打入apk包。

1.3   自定义主dex中必须要包含的类

如果有需求必须把某些类打入主dex文件,可以自行配置一个maindexlist.txt文件置于app目录下,并在txt文件内标明自定义想要被打入主dex文件的类,最后别忘了multidexjar包中有9个类必须被打入主dex文件。maindexlist.txt文件如下所示:

//自定义类
com/calvin/util/Util.calss
//jar包中的9个类
android/support/multidex/BuildConfig.class
android/support/multidex/MultiDex$V14.class
android/support/multidex/MultiDex$V19.class
android/support/multidex/MultiDex$V4.class
android/support/multidex/MultiDex.class
android/support/multidex/MultiDexApplication.class
android/support/multidex/MultiDexExtractor$1.class
android/support/multidex/MultiDexExtractor.class
android/support/multidex/ZipUtil$CentralDirectory.class
android/support/multidex/ZipUtil.class

最后在Gradle加入afterEvaluate节点进行如下配置即可:

afterEvaluate {  
        tasks.matching {  
           it.name.startsWith('dex')  
        }.each { dx ->  
           Def listFile = project.rootDir.absolutePath +  '/app/maindexlist.txt'  
           if (dx.additionalParameters == null) {  
              dx.additionalParameters = []  
           }  
              dx.additionalParameters += '--multi-dex'  //表示方法数越界生成多个dex
              dx.additionalParameters += '--main-dex-list=' + listFile //类列表,这里即txt文件路径
              dx.additionalParameters += '--minimal-main-dex'   //表示只有main-dex-list指定的类会被置于主dex
        }  
}

2     总结

1)方法数自己想办法能减少就尽量减少,实在不行就使用Multidex方案,Multidex解决方法数越界容易且高效,但是不可避免的是额外的dex文件会降低应用启动速度

2)在应用安装过程中系统会运行一个名为dexopt的程序来优化dex文件dexopt使用LinearAlloc缓冲区来存储应用的方法信息Android 2.x中该缓冲区只有5MB4.x提高到了8MB16MB。当方法数量过多(甚至不需要超过65K)时,可能会超过缓冲区容量限制而报错。

因此Multidex方案Maybe会在4.0以前的手机上失效。但是使用该方案产生很多个dex文件,缓冲区超过16MB一样会在4.0以后的手机上崩溃。所以在4.0以前的手机上需要做兼容性测试,4.0以后的手机上也不能因为有了Multidex方案而过于放纵~

3    5.0以后

从Android5.0开始,使用ART虚拟机代替Dalvik虚拟机,ART虚拟机在应用安装期间,会执行一个预编译的操作,扫描APK中所有的dex文件并把他们编译成一个单一的.oat文件,然后在应用运行的时候直接去加载这个.oat文件,而不是一个个的去加载.dex文件。

最后请大家多留言交流,还有多点赞支持~

转载请注明出处:Android开发——解决方法数越界问题_SEU_Calvin的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值