DexException: Too many classes in --main-dex-list, main dex capacity exceeded

main_dex 撑爆问题

这是一个众所周知的问题,很难在不久的将来得到修复。问题是 Dalvik 只支持65535(2 ^ 16 - 1)个类。一旦所有设备都使用原生ART,它就不再是问题了。其实是Dalvik的bug

 

方案分析:

1.将app/gradle中minSdkVersion改为21。(这个是趋势,但是不适用所有企业,有的企业为了更宽广的用户面,会要求兼容到4.x)

(ps:一,Android 4.4开始开始引入ART,到5.0已经成为默认选择. 二,Android 5.0    21    LOLLIPOP)

2.将dx参数中keepRuntimeAnnotatedClasses设为false。特别是用到了注解的项目要记得配置这个属性.

android {
    ...
    dexOptions {
        // annotation keep,即是否保留运行时的注解
        keepRuntimeAnnotatedClasses false
    }
}

部分同学添加这个属性后可以解决,部分同学添加主dex依然撑爆,请同时使用最终解决方案

3.先来看下Multidex的编译过程,它由三个不同的gradle task组成:

这个task会读取项目的AndroidManifest.xml文件中注册的application、Activity、service、receiver、provider、instrumentation相关类,并将其class文件路径写到文件manifest_keep.txt中,此文件目录不一,受gradle版本影响。

我们用的是3.2.1,

就在图示目录

DexException: Too many classes in --main-dex-list, main dex capacity exceeded_第1张图片

这个task会调用ProGuard并根据上一步生成的manifest_keep.txt文件内容去压缩class,剔除没有用到的class,生成一个精简的jar包componentClasses.jar

DexException: Too many classes in --main-dex-list, main dex capacity exceeded_第2张图片

这个task会根据上一步生成的componentClasses.jar去寻找这里面的各个class文字中依赖的class,比如一个class中有一成员变量X,那么X就是依赖的class,componentClasses.jar中所有的class和依赖的class路径都会被写入到文件maindexlist.txt中,这个文件中的类都会被编译进主的classes.dex中去。

 

呐,知道了main-dex的生成过程。怎么优化就很简单了,我们定下

最终解决方案,修改maindexlist.txt文件

DexException: Too many classes in --main-dex-list, main dex capacity exceeded_第3张图片

1.在app/gradle下新增一个task,遍历原来的maindexlist

DexException: Too many classes in --main-dex-list, main dex capacity exceeded_第4张图片

2.根据业务定义一个不包含类列表exclude_class.txt,剔除maindexlist中exclude_class自定义的所有类。

DexException: Too many classes in --main-dex-list, main dex capacity exceeded_第5张图片

3.替换成新的maindexlist

 

clean成功后,重新打包就可以了。

 

补充:当集成成功后依然撑爆的话,请检查下图中这一行,不以图中为准,以实际项目生成的为准

着重检查点

第一,盘符是否对应(前后正反斜杠是否一致,${project.buildDir}这句代码在linux和windows获取到的斜杠正反不一致),

第二,文件名大小写是否一致(部分为mainDexList.txt),

第三,文件路径是否正确(部分为buidl/intermediates/multi-dex/${variant.dirName}/maindexlist.txt)

 

文中用到的都放在这里,懒人福利


 

你可能感兴趣的:(主dex撑爆,main,dex,capacity,exceeded,Android65536)