Android 65k 问题

文/zerob13(简书作者)
原文链接:http://www.jianshu.com/p/245022d136e1
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

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

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

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

multidex support library

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

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

android {
   ...
   shitAppConfig {
     ...
     multiDexEnabled true
   }
}

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

public class ShitApplication extends MultiDexApplication {
   ...
}

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

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

还有一种情况就是没有继承过 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 文件,就不存在找不到的问题了。

当然,真遇到这个问题的时候,还是建议看看架构上面有没有可以改良的地方。实在不行把一个 App 拆两个也行啊,别总想搞个大新闻,你说是吧。

你可能感兴趣的:(android,65K)