解决传说中的 Android 65k 问题

在 Android 开发中,有一个之前很少听说,最近偶尔江湖传闻听到过的问题,就是 65k 问题。什么是65k问题呢?其实很简单,就是 Android 有个限制,你的每个 App 中函数最多只能有 65536 个。

这个限制其实是这样的,因为在编译成 Dalvik 字节码,也就是把你的 Class 们生成打包到一个 classes.dex 中去的时候呢,编译器会给你的 App 中所有的函数方法指定一个 ID, 然后每一个 classes.dex 中 ID 的范围是 [0, 0xffff] 。 所以,你懂的,就有了那么一个 65k 的问题。

当然大部分应用程序里路上是不会遇到这个问题的,毕竟 65k 个函数也很多了,但是考虑到现在各种引入 SDK,而且尤其是大公司的程序往往会有很多匪夷所思的功能,最后代码越来越臃肿,指不定哪天就遇到了。不过还好,这个问题也不难解决,Google官方已经给出了解决方案:

multidex support library

简单翻译下,原理就是编译的时候不再是单纯编译到一个 Dex 文件中去,而是切分成多个 Dex 文件。这样每个文件都允许 65536 个函数,肯定是够用了的。下面说下具体的操作。

首先就是导入这个库,这个 Eclipse 和 Android Studio 不太一样,但是具体就不说了,因为太常见了。不过如果用的是新版本的 Android Studio 似乎已经无需导入这个库,貌似 IDE 直接支持了。只需要把配置文件中的 multiDexEnabled 设置成 true 就可以了,大概就是下面这个样子:

defaultConfig {
        applicationId "com.example.hecun.myapplication"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

然后就是让你的 Application 类继承自 MultiDexApplication 这个类 ,例如:

public class MyApplication extends MultiDexApplication {
    @Override
    public void onCreate() {
        super.onCreate();
    }
}

假如不方便修改继承(比如已经继承了其他的封装了的 Application)那么久稍微复杂一点,重载一下attachBaseContext,代码如下:

public class MyApplication extends MultiDexApplication {
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

至于为什么重载attachBaseContext方法本人不是很明白,为什么不直接写在onCreate方法中,只是知道Application中方法的执行顺序如下

解决传说中的 Android 65k 问题_第1张图片

还有一种情况就是没有继承过 Application 类怎么办?这种最方便,打开你的 AndroidMainfest 文件,在 application tag 中加入这个:

android:name="android.support.multidex.MultiDexApplication"

到此,问题算是解决了。但是这并不完美,在 Android 5.0之前,你还需要保证你的 Activity , Service等等基本上 Dalvik需要直接找你的东西都放在第一个 dex 中,否则你的 App 就会挂掉。这部分内容说起来比较复杂,我建议直接去看 Google 官方的说明,Building Apps with Over 65K Methods 。当然,如果你的程序只支持 Android 5.0 以后的机器,那就不用担心了,因为 ART 会把多个 dex 合并成一个 oat 文件,就不存在找不到的问题了。

你可能感兴趣的:(解决传说中的 Android 65k 问题)