博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android开发——解决方法数越界问题
阅读量:4046 次
发布时间:2019-05-24

本文共 2978 字,大约阅读时间需要 9 分钟。

0. 前言

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

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

带着这个问题开始这篇文章,转载请注明出处:

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的功能

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

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.classandroid/support/multidex/MultiDex$V14.classandroid/support/multidex/MultiDex$V19.classandroid/support/multidex/MultiDex$V4.classandroid/support/multidex/MultiDex.classandroid/support/multidex/MultiDexApplication.classandroid/support/multidex/MultiDexExtractor$1.classandroid/support/multidex/MultiDexExtractor.classandroid/support/multidex/ZipUtil$CentralDirectory.classandroid/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文件。

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

转载请注明出处:

你可能感兴趣的文章
Jenkins - sonarqube 代码审查
查看>>
Jenkins + Docker + SpringCloud 微服务持续集成(一)
查看>>
Jenkins + Docker + SpringCloud 微服务持续集成 - 单机部署(二)
查看>>
Jenkins + Docker + SpringCloud 微服务持续集成 - 高可用集群部署(三)
查看>>
Golang struct 指针引用用法(声明入门篇)
查看>>
Linux 粘滞位 suid sgid
查看>>
C#控件集DotNetBar安装及破解
查看>>
Winform皮肤控件IrisSkin4.dll使用
查看>>
Winform多线程
查看>>
C# 托管与非托管
查看>>
Node.js中的事件驱动编程详解
查看>>
mongodb 命令
查看>>
MongoDB基本使用
查看>>
mongodb管理与安全认证
查看>>
nodejs内存控制
查看>>
nodejs Stream使用中的陷阱
查看>>
MongoDB 数据文件备份与恢复
查看>>
数据库索引介绍及使用
查看>>
MongoDB数据库插入、更新和删除操作详解
查看>>
MongoDB文档(Document)全局唯一ID的设计思路
查看>>