android关于多dex打包的理解

读完本文需要5分钟

android引用太多外部jar包的时候会导致方法数过多,也就是我们经常说的95536方法数限制;

所以要使用多dex打包

一、为什么要使用multidex?

1.现状:android引用太多外部jar包的时候会导致方法数过多,也就是我们经常说的95536方法数限制;

[onversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536]

2.原因:android会把每个类中的方法ID检索起来,统一保存在链表结构中,但链表的长度是用short表示的,short占用的取值范围是2个字节,2的-15次方到2的15次方-1。

3. 解决方法:1、去掉无用的多余的方法;2、尽量少引用大的jar包;3、使用multidex打多个dex;4、复杂模块使用jni实现;

二、如何使用multidex?

1、使用的时候还是比较简单的,要在app build.gradle中的defaultconfig中声明multiDexEnable true;

2、重写自己的application继承android自己的MultiDexApplication,然后重写application的attachBaseContext的方法,在attachBaseContext中调用android提供的MultiDex.install(this);

[注意]使用上面的分包需要使用android build tool升级到21.1版本

三、android multidex原理

1、dex分割 2、dex加载

1、dex分割

反编译过apk的同学知道,编译后的文件夹中包括多个dex文件,然而谷歌是怎么生成这些dex文件的,相信知道的没几个吧,那么今天我们就一一给大家解释下,具体的分割生成dex的。

(1)首先自动扫描所有代码进入到main-dex-list中;

(2)然后将编译后的class进行主从拆分,生成主从class;

(3)将主从class分别打包成主从dex,并放在apk的不同位置;

怎么生成main-dex-list呢?

1)调用 proguard 的 shrink 操作来生成一个临时 jar 包;

2)将生成的临时 jar 包和输入的文件集合作为参数,然后调用com.android.multidex.MainDexListBuilder 来生成主 dex 文件列表。

主dex:根据proguard中keep,将keep的代码打包进入主dex,作为主dex的入口类;和入口类相关的其它代码通过com.android.multidex.MainDexListBuilder类打包进主dex;

2、dex加载

因为Android系统在启动应用时只加载了主dex(Classes.dex),其他的 dex 需要我们在应用启动后进行动态加载安装。 Google 官方方案是如何加载的呢,Google官方支持Multidex 的 jar 包是 android-support-multidex.jar,该 jar 包从 build tools 21.1 开始支持。

MultiDex.install(this);执行的过程会从 apk 中提取出所有的从 dex(classes2.dex,classes3.dex,…),然后通过反射依次安装加载从dex,并合并到放在BaseDexClassLoader的DexPathList的 Element数组。

如果大家觉得好,大家转载的同时,也动动小手点点文章左上角的订阅, 关注“AndroidDeveloper”, 或者加群“556062010”联系到我, 这样就能每天第一时间收到作者推送的文章啦, 谢谢大家的关注。

举报
评论 0