大型商业性的app,业务越来越多;并且项目中引用了许多的sdk以及公共jar包,导致dex文件中的方法数超过65536;导致程序不能编译运行,如何解决?
错误截图:
应用中Dex文件中的方法数超过了最大值65536的上限,就是应用爆棚.
oogle看来也意识到了目前应用方法数爆棚的问题, 目前在已经在API 21中提供了通用的解决方案,那就是android-support-multidex.jar. 这个jar包最低可以支持到API 4的版本(Android L及以上版本会默认支持mutidex).
一个DEX文件中method个数采用使用原生类型short来索引文件中的方法,也就是4个字节共计最多表达65536个method,field/class的个数也均有此限制。对于DEX文件,则是将工程所需全部class文件合并且压缩到一个DEX文件期间,也就是Android打包的DEX过程中, 单个DEX文件可被引用的方法总数被限制为65536。(包括第三方jar包)
分割Dex,多工程: 把所需要的.class文件或者是Jar文件和一些源码一起编译生成一个Jar文件。然后使用Android SDK提供的dx工具把Jar文件转成Dex文件。
具体集成:
第一步:
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
第二步:
从sdk\extras\android\support\multidex\library\libs 目录将android-support-multidex.jar导入工程中
第三步:
如果你的工程中已经含有Application类,那么让它继承android.support.multidex.MultiDexApplication类,
如果你的Application已经继承了其他类并且不想做改动,那么还有另外一种使用方式,覆写attachBaseContext()方法: 例如:
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
第四步:在build.gradle文件的defaultConfig的节点下 添加一行代码:
android {
defaultConfig {
applicationId "com.xunpige.nengwu"
minSdkVersion 14
targetSdkVersion 21
multiDexEnabled true
}
}
注意事项:
对于dex 的--multi-dex 选项设置与预编译的library工程有冲突,因此如果你的应用中包含引用的lirary工程,需要将预编译设置为false:
android {
dexOptions {
javaMaxHeapSize "4g"
preDexLibraries = false
}
}
在
dexOptions
中有一个字段用来增加java堆内存大小.
DEX文件安装到设备的过程非常复杂,如果第二个DEX文件太大,可能导致应用无响应。此时应该使用ProGuard减小DEX文件的大小。
由于Dalvik linearAlloc的Bug,应用可能无法在Android 4.0之前的版本启动,如果你的应用要支持这些版本就要多执行测试。