<读书笔记> Android dex文件 64k 方法数限制

来源:互联网 发布:淘宝评分 编辑:程序博客网 时间:2024/06/10 10:32

Android当个dex文件所能够包含的最大方法数为65536,一般来说一个简单的应用很难达到65536,但是对于一些大型的应用来说,65536就很容易达到。当达到这个峰值以后,编译器就无法完成编译工作并抛出异常如下:

UNEXPECTED TOP-LEVEL EXCEPTION:com.android.dex.DexIndexOverflowException:method ID not in [0,0xffff]:65535 at com.android.dx.merge.DexMerger$6.updateIndex(Dexmerger.java:502)at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(Dexmerger.java:283)at com.android.dx.merge.DexMerger.mergeMethodIds(Dexmerger.java:491)at com.android.dx.merge.DexMerger.mergeDexes(Dexmerger.java:168)at com.android.dx.merge.DexMerger.merge(Dexmerger.java:189)at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454)at com.android.dx.command.dexer.Main.runMonoDex(Main.java:303)at com.android.dx.command.dexer.Main.run(Main.java:246)at com.android.dx.command.dexer.Main.main(Main.java:215)at com.android.dx.command.Main.main(Main.java:106)

针对该问题,我们想到的应该是删除无用的代码和第三方库。但是在很多情况下,我们删除了无用的代码,方法还是越界,很多应用会考虑用插件化机制动态加载部分,通过将一个dex拆分成两个或多个dex,这就在一定程度上解决了方法数越界的问题,但是插件化是一套重量级的技术方案,并且兼容性的问题比较多。

解决方案

在2014年Google提出了multidex的解决方案,通过multidex可以很好的解决方法数越界的问题,并且使用起来非常简单。在androidStudio和Gradle的编译环境中,使用multidex的话Android SDK 的bulide 版本为21.1及以上,接着修改工程中app目录下的build.gradle文件,在defaulConfig中添加 multiDexEnabled true这个配置项,在dependencies中添加multidex依赖:compile 'com.android.support.multidex:1.0.0',如下所示:![这里写图片描述](http://img.blog.csdn.net/20170802164449500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbW9tb2xlbGU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

配置完成之后还需要在代码中加入支持multidex的功能,这里主要邮三种方案:

  1. 第一种
    在manifest文件中指定AppLication为MultiDexApplication,如下所示:
<application    android:name="android.support.multidex.MultiDexApplication"    android:allowBackup = "true"    android:icon = "@mipmap/ic_launcher"    android:label = "@string/app_name"    android:theme="@style/AppTheme"></application>
  1. 第二种
    让应用的Application继承MultiDexApplication,如下所示:
public class TestApplication extends MultiDexApplication{}
  1. 第三种
    如果不想让应用的Application继承MultiDexApplication,还可以选择重写Application的attachBaseContext方法,这个方法比Application的onCreate()先执行,如下所示:
public class TestApplication extends MultiDexApplication{    @Override    protected void attachBaseContext(Context base){        super.attachBaseContext(base)        MultiDex.install(this);    }}

完成上述的工作,再进行编译,发现编译通过了和正常安装了。

阅读全文
0 0