1,64k限制的原因
Android的 APK文件本质是一个压缩文件,它里面包含的classes.dex文件是可执行的Dalvik字节码文件,这个dex文件存放的是所有编译过后的Java代码。Dalvik可执行文件规范限制了单个dex文件最多能引用的方法数是65536个。这其中包括了Android Framwork,App自身和第三方库的方法
2,使用MultiDex解决64k限制问题
- 在Android 5.0之前,系统使用的Dalvik虚拟机来执行Android应用,Dalvik为每个应用生成一个dex文件,默认情况下只生成一个classes.dex文件,为了规避单个dex文件超过64k的问题,我们需要拆分dex文件,拆分后存在classes.dex,classes1.dex ...等多个dex文件。应用启动的时候,会先去加载classes.dex文件,称为主dex文件,然后再依次去加载其他的dex文件,称为从dex
- 从Android 5.0之后,Android采用Art虚拟机代替Dalvik虚拟机。Art依然是支持多个dex文件,不同的是它会在安装应用期间执行一个预编译操作,将dex预编译成单个.oat文件,在应用启动的时候去加载.oat文件,提升应用启动速度
3,如何避免出现64k方法数限制
- 当应用需要使用multiDex的时候,不可避免的降低了性能,唯一的办法就是应用的方法数永远低于64k
- 检查应用的直接和间接第三方库依赖,引入一个第三方库需要综合考虑这个库的体积方法数,性能等等
- 使用proguard移除无用的代码
4,配置MultiDex
由于各种原因,我们没有办法将方法数降低到64k以下,那么就之后使用Google的MultiDex解决方案。Android的Gradle,首先需要配置Application Molule的build.gradle,使用MultiDex函数库的依赖,同时使用MultiDex
android {
.....
defaultConfig {
.....
//使用MultiDex支持
multiDexEnabled true
}
.....
}
dependencies {
.....
implementation "com.android.support:multidex:1.0.1"
}
然后在自定义的Application类中,做如下声明
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
4, MultiDex的限制
- 如果应用的从Dex文件过大,可能出现ANR,原因是Dalvik虚拟机会对所有的Dex文件执行dexopt操作,生成ODEX文件,这个过程非常复杂和耗时
- 如果App依旧支持Api level 14之前的系统,那么在上线前要严格测试,否则可能出现启动App出现错误
- 由于Dalvik虚拟机的linearAlloc的限制(Dalvik虚拟机用来加载类的堆内存被硬编码了),在Android 5.0之后使用Art虚拟机,不再有linearAlloc的限制
- 当引入MultiDex之后,不可避免的有主dex和从dex文件,当应用启动所需要的类都必须放在主Dex文件中,否则会出现NoClassDefFoundError
5,开发阶段优化MultiDex的构建
MultiDex之所以会增加显著的构建时间,原因在于构建系统需要经过复杂的计算决定哪些类要包含到主dex文件中,哪些类可以包含在从Dex文件中
为了解决这个问题,我们可以在gradle中配置开发阶段使用的sdk版本和生产环境使用的sdk版本,提升开发阶段的的效率
productFlavors {
dev {
minSdkVersion(21)
}
prod {
minSdkVersion(rootProject.ext.android.minSdkVersion)
}
}
网友评论