1. 简介
在安卓开发中,当开发到一定的版本,apk有可能会遇到64K方法问题。指的是Android中的可执行文件.dex中的Java方法引用超过65536。
2. 使用MultiDex解决64K限制问题
Android5.0之前,系统使用的是Dalvik虚拟机来执行应用。默认情况下,Dalvik为每个apk只生成一个classes.dex文件,为了规避单个.dex文件方法个数超过64K的问题,我们需要拆分这个单一的dex文件,拆分后可能出现classes.dex,classes2.dex等多个.dex文件。应用启动的时候会先加载classes.dex文件,我们称之为主dex文件。
Android5.0之后,Android开始使用ART虚拟机来代替Dalvik虚拟机,ART天然支持从apk文件中加载多个.dex文件,在应用安装期间,它会执行一个预编译操作。将所有的dex编译成一个单一的.oat文件,在应用运行是去加载这个.oat文件,而不是一个一个的加载.dex文件。
3. 规避方法
4. 配置
android {
defaultConfig {
multiDexEnabled true
}
}
dependencies {
implementation 'com.android.support:multidex:1.0.3'
}
|
引入MultiDexApplication
三种方法
配置当前项目的清单文件
<applicationandroid:name="android.support.multidex.MultiDexApplication"</application>
当前的Application继承MultiDexApplication
在attachBaseContext方法中初始化MultiDex
@Override protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
5. 局限性
前面我们说过, MultiDex Support Library只是一个不得已而为之的方案,它本身并不是完美的,因此将它集成到项目中,需要经过完整的测试才能上线,可能会出现应用性能下降等问题, MultiDex Support Library的局限性如下。
应用首次启动时 Dalvik虚拟机会对所有的.dex文件执行 dexopt操作,生成ODEX文件,这个过程很复杂且非常耗时,如果应用的从dex文件太大,可能会导致出现ANR。
在 Android4.0( API level14)之前的系统上,由于 Dalvik linearalloc的bug(见Isse225861),使用 Multidex的应用可能启动失败。如果你的应用还支持低于 API level14的系统版本时,那么在上线之前需要针在这些低版本系统经过严格充分的测试,否则用户可能会在启动你的APP时出现错误。理论上,使用 Proguard的压缩功能可以减少或者消除这些潜在的问题。当然,目前低于 Android4.0的系统使用量已经很少了,建议直接将应用的 minSdkversion设置为14,这样问题也就不存在了。
由于 Dalvik的线性内存分配器 linearalloc的限制(见Isue7803532),使用 MultiDex的应用在出现很大的内存分配时,可能会导致应用崩溃。根本原因是 Dalvik虚拟机用来加载类的堆内存大小被硬编码了, Android2.3以下是5M, Android2.3是8M,这个内存
分配的限制在 Android4.0( API level14)已经增加到了16M,但是在 Android5.0(APIlevel21)之前的系统上运行的APP,还是有可能会超出这个限制,从而导致崩溃。当然 Android5.0开始由于使用了ART虚拟机,因此不再存在 linear Alloc的问题。当引入 Multidex机,时,必然会存在主dex文件和从dex文件,应用启动所需要的类必须放到主dex文件中,否则会出现NoClassDefFoundError的错误。Android构建工具自动帮我们]处理了Android系统相关的依赖,但对又于应用自己引入的第三方函数库,如果还依赖其他的一些东西,例如通过反射调用Java类,或者调用NDK层代码的Java方法,这些可能就不会被放到主dex文件中,如果在应用启动时需要用到,那么必然出现问题。
部分参考自Android高级进阶
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)