当一个app的功能越来越复杂,代码量越来越多,也许有一天便会突然遇到下列现象:
1. 生成的apk在2.3以前的机器无法安装,提示INSTALL_FAILED_DEXOPT
2. 方法数量过多,编译时出错,提示:
Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536
出现这种问题的原因是:
1. Android2.3及以前版本用来执行dexopt(用于优化dex文件)的内存只分配了5M
2. 一个dex文件最多只支持65536个方法。
针对上述问题,也出现了诸多解决方案,使用的最多的是插件化,即将一些独立的功能做成一个单独的apk,当打开的时候使用DexClassLoader动态加载,然后使用反射机制来调用插件中的类和方法。这固然是一种解决问题的方案:但这种方案存在着以下两个问题:
1. 插件化只适合一些比较独立的模块;
2. 必须通过反射机制去调用插件的类和方法,因此,必须搭配一套插件框架来配合使用;
* 在Gradle和代码中配置使用MultiDex
由于Android 的Gradle插件在Android Build Tool 21.1开始之处使用mulitidex,所以我们需要使用Android Build Tools 21.1及以上版本,修改app目录下的build.gradle文件:
(1) 在defaultConfig中添加multiDexEnabled true这个配置项
(2)在dependencies中添加multidex的依赖 compile 'com.android.support:multidex:1.0.0'
注意:buildToolsVersion要高于21.1
配置如下:
// defaultConfig
multiDexEnabled true
// dependencies
compile files('libs/android-support-multidex.jar')
* 在Gradle中配置好之后,我们还需要在代码中加入支持multidex的功能,有三种方案可选
1) 在manifest文件中指定Application为MultiDexApplication
2) 写一个Application类并继承MultiDexApplication,并在AndroidManifest.xml的application标签中进行注册(在application标签中增加name属性,并添加自己的Application类名即可),如果不是想重写MultiDexApplication中一些方法的话,还是方案一更方便些
3) 如果不想按方案二继承,我们可以重写Application的attachBaseContext方法,注意,这个方法比onCreate方法先执行。具体方法是创建一个新类,继承Application,然后重写attachBaseContext方法,并在AndroidManifest.xml的application标签中进行注册(与方案二注册相同)