65K

557 阅读2分钟

什么是65K问题

在android5.0之前,每一个android应用中只会含有一个dex文件,但是这个dex的方法数量被限制在65535之内,这就是著名的64K(64*1024)事件。

当Android系统启动一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised。DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。

www.imooc.com/article/433…

这包含 Android FrameWork、依赖的 jar 包以及应用本身的代码中所有的方法,当应用的方法达到 65536 后,编译器就无法完成编译,会抛出异常

为了解决这个问题,Google官方推出了这个类似于补丁一样的support-library,MultiDex。

当方法数超过 65536 的时候,生成多个 dex 文件,把应用启动时必须用到的类和该类的直接引用类放到 Main dex 中,把其他类放到 Second dex 中。当应用启动之后,动态加载 Second dex,从而避免 65k 问题

使用这个库后,我们的APP不再只会仅有一个dex文件,可能会产生多个dex文件

Multidex的基本使用

配置build.gradle

android {

    compileSdkVersion 21
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
    //使用google提供的分包库
    implementation 'com.android.support:multidex:1.0.2'
    implementation 'com.android.support:multidex-instrumentation:1.0.2'
}

配置AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>

让应用支持多 DEX 文件,在官方文档中描述了三种可选方法:

1、在 AndroidManifest.xml 的 application 中声明 android.support.MultiDex.MultiDexApplication;

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>

2、如果你已经有自己的 Application 类,让其继承 MultiDexApplication;

public class MyApplication extends MultiDexApplication {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
    }
}

3.如果你的 Application 类已经继承自其它类,你不想/能修改它,那么可以重写 attachBaseContext() 方法:

@Override 
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

添加这些配置后,编译工具会构建出一个主 DEX 文件(classes.dex)和其他附属 DEX 文件(classes2.dex,classes3.dex 等,如果需要的话),编译系统会将他们打包到 Apk 文件中,可以通过配置文件来控制哪些代码放到主 DEX 包中。

MultiDex存在的问题,优化方案

Android 方法数 65k 问题 Android使用Multidex突破64K方法数限制原理解析