MultiDex

  先说下为什么有这篇文章,app刚完成第一版开发(笔者内心是非常崩溃的,接手的项目其实前景还不错,但是第一版被玩坏了,做第一版的产品,UI,测试,开发都走了,然后来接手这个项目,全是一脸懵逼,前期规划的太烂),然后运营也开始进行培训,刚好白天运营同事拿过来一款手机,Android4.4的版本,然后运行app就闪退,于是开始寻找这个原因就有了这篇文章。

5.0以前

  先说下,在Android5.0以前,Android使用的是dalvik虚拟机,而dalvik虚拟机为每一个apk只生成一个classes.dex文件(dex全称Dalvik Executable Format,是java文件编译后的class文件的集合)。那么重点来了,这个dex文件它所保存的classes的方法个数是0~65535,随着业务的不断增加,迟早有一天会超过这个限制,那么该怎么解决方法数64k的限制呢?这个时候就出现了multidex这个东西。

5.0以后

  前面说了Android5.0版本之前使用的是Dalvik虚拟机,对每个apk只会生成一个classes.dex文件。而Android5.0开始,使用的是ART(Android Runtime),它本身支持从APK加载多个DEX文件,它会在apk安装的时候执行一次预编译,如果发现有多个dex文件,它会将其整合成一个.oat的文件供Android设备执行。因此如果minSdkVersion高于Android5.0,就不需要multidex库的支持。

配置multidex

minSdkVersion21或更高

  如果minSdkVersion为21或者更高,我们只需要在app的build.gradle文件下配置multiDexEnable为true即可。

1
2
3
4
5
6
7
8
9
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 28
multiDexEnabled true
}
...
}

minSdkVersion低于21

  如果minSdkVersion低于21,那么我们需要使用multidex support library。
首先,修改build.gradle文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 28
multiDexEnabled true
}
...
}

dependencies {
compile 'com.android.support:multidex:1.0.3'
}

  然后修改Application。

  1. 如果没有重写Application,我们需要在AndroidManifest.xml文件中指定application标签的name属性为MultiDexApplication;

    1
    2
    3
    4
    5
    6
    7
    8
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
    android:name="android.support.multidex.MultiDexApplication" >
    ...
    </application>
    </manifest>
  2. 如果重写了Application,可以让其继承MultiDexApplication;

    1
    public class MyApplication extends MultiDexApplication { ... }
  3. 如果既重写了Application,又继承了其他的Application,那么可以使用multiDex.install(context)的方式。

    1
    2
    3
    4
    5
    6
    7
    public class MyApplication extends SomeOtherApplication {
    @Override
    protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
    }
    }

  注意一点,不要在MultiDex.install()方法之前通过反射或者JNI执行任何代码,这会导致出现ClassNotFoundException。

  然后我们再构建项目,它会生成一个primary dex(classes.dex),和若干个support dex(classes2.dex…),最后构建系统会将这些dex文件打包到apk中。
在运行的时候,multidex APIs会使用特定的类加载器检索所有可用的DEX文件,而不仅仅只是在主classes.dex文件中进行检索。

官方文档

https://developer.android.google.cn/studio/build/multidex#about
https://developer.android.com/studio/build/multidex#about

本文标题:MultiDex

文章作者:严方雄

发布时间:2018-11-21

最后更新:2018-11-21

原始链接:http://yanfangxiong.com/2018/11/21/MultiDex/

0%