一:解决什么问题
当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODex的效率会比直接执行Dex文件的效率要高很多。
但是在早期的Android系统中,DexOpt有一个问题,DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。当一个项目足够大的时候,显然这个方法数的上限是不够的。尽管在新版本的Android系统中,DexOpt修复了这个问题,但是我们仍然需要对低版本的Android系统做兼容。
比如:微信app经过分包后,我们解压其apk文件:
从中我们可以看到微信经过分包处理之后有3个dex文件
二:怎么使用
(1)在App所属的build.gradle里面
android {
......
defaultConfig {
multiDexEnabled true
......
}
}
(2)在你自定义的Application(这个一般项目里面都有)
MultiDex.install(this);//初始化
ok.这两步就搞定了!
三:原理呢
(1)首先简单了解Java中的常见类加载器
A:BootStrapClassLoader
纯c++实现的类加载器,没有对应的Java类,主要加载jre/lib下的核心库
B:ExtClassLoader
主要加载jre/lib/ext下的扩展包
C:AppClassloader
主要加载CLASSPATH路径下的包
(2)类加载器是怎么加载类的
关键词:父委托加载机制
类加载器加载类用到的方法:
父委托机制可以用下图说明:
(3)下面看下Android常用的类加载器
A:PathClassLoader
加载data/app 下的apk文件,主要用于加载已经安装了的apk
B:DexClassLoader
加载路径需要在创建DexClassLoader时传入,也就是说可以加载任何路径下的apk,jar,dex
继承关系:
(4)具体 MultiDex.install(this) 做了什么,请参考:
http://allenfeng.com/2016/11/17/principle-analysis-on-multidex/