Android中的MultiDex

举报
月色很美 发表于 2018/12/19 08:58:41 2018/12/19
【摘要】 1. 简介在安卓开发中,当开发到一定的版本,apk有可能会遇到64K方法问题。指的是Android中的可执行文件.dex中的Java方法引用超过65536。2. 使用MultiDex解决64K限制问题Android5.0之前,系统使用的是Dalvik虚拟机来执行应用。默认情况下,Dalvik为每个apk只生成一个classes.dex文件,为了规避单个.dex文件方法个数超过64K的问题,我...

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. 规避方法

  • 检查引用的依赖

  • 使用Proguard,移除没有使用的类、字段、方法和属性

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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。