随着项目越来越大,需求越来越复杂,要导入的库也随之增加。
这不,刚更新了几个库(有一些库的新版本拆分成了两个 jar ),然后 run,结果就卡住了,log 信息:
The number of method references in a .dex file cannot exceed 64K.
搜索了一下,大概的意思就是:Android 打包的 DEX 过程中, 单个 DEX 文件可被引用的方法总数被限制为 65536,现已超出这个数目。
试着恢复某些库为旧版本,run 成功。但觉得这样下去不行,哪天又要导入什么库的话那还是会出现这个问题,所以这个问题还是得早点解决。
接着就是各种找资料,基本上推荐的解决方法都是利用这个:android-support-multidex.jar
下面简单说说流程:
首先配置 build.gradle:
defaultConfig { ... multiDexEnabled true ... } dependencies { ... compile 'com.android.support:multidex:1.0.1' ... }
(PS:也可以导 jar ,当然为了方便还是建议直接 compile )
接下来到配置 Application,分几种情况:
第一种是没有自己写 Application,那么我们就可以直接在 AndroidManifest.xml 里面设置:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="..."> <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application> </manifest>
第二种情况是已经自己写了 Application,那么这也分两种情况:
1、Application 已经继承了其它类,但又不想做改动,那么我们需要覆写 attachBaseContext(加入 MultiDex.install(this) ; ):
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this) ; }
2、Application 没有继承其它类,那么有两种方案,一种是直接让其继承 android.support.multidex.MultiDexApplication ,另一种就是跟第一种情况那样进行覆写。
至此配置完毕,然后再 run 一遍,结果又卡住了,log 信息如下:
Error:java.lang.OutOfMemoryError: GC overhead limit exceeded.
官方定义就是:通过统计GC时间来预测是否要OOM了,提前抛出异常,防止OOM发生。并行/并发回收器在GC回收时间过长时会抛出OutOfMemroyError。过长的定义是,超过98%的时间用来做GC并且回收了不到2%的堆内存。用来避免内存过小造成应用不能正常工作。
解决方法很简单,只需要简单配置下 build.gradle:
dexOptions { ... javaMaxHeapSize "4g" }
(增加java堆内存大小)
(PS:不知道是心理作用还是什么的,感觉配置了这个还有拆分 Dex 后 run 的时间比以前快了)
当然顺便也记录下可能还会连带出现的一个问题:
com.android.dex.DexException: Library dex files are not supported in multi-dex mode.
大概解释就是:multi-dex 选项设置与预编译的 library工程有冲突
解决方法(配置 build.gradle):
dexOptions { ... preDexLibraries = false }
(将预编译设置为 false)