配置方法数超过 64K 的应用
前言:
当应用程序不断膨胀以及引用的第三方库越来越多时。应用程序的方法数很有可能超过65536 ,就会报出以下异常。
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536
此时强烈建议大家查看google官方文档解决该问题。
第一次看到这个异常时,我的内心还是很激动的,感觉亲眼见证了程序一步步的成长。本以为按照官方文档的配置会很顺利解决,但是中途还是遇到了一些问题,下面记录一下最基本的配置步骤以及我遇到的一些问题。
基本配置:
- 修改build.gradle文件
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
- 修改manifest.xml以引用 MultiDexApplication 类
- <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.multidex.myapplication">
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
如果程序已经重写了Application类,manifest.xml中的package仍填写自己引用的Application类,并在重写的类中重写attachBaseContext()方法。
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
遇到的问题:
- 配置完成会报错
遇到这个问题主要因为当时编译的工程有两个module,其中一个module作为library库,一个作为主工程。我将依赖库以及multiDexEnabled的配置放在了library库的buildl.gradle文件中,导致编译不成功。
后来想一下这样不成功很正常啊,dex文件的生成肯定与最终生成apk的主工程有关,库可以是第三方开发的,可以是自己写的,所以分包这种事一定是主工程做。
multiDexEnabled 放错位置
由于我编译的主工程设置了变形,gradle文件中设置了相应的变形,配置如下:
android {
productFlavors {
normal {
versionCode getVersionCode()
versionName getVersionName()
minSdkVersion 16
targetSdkVersion 19
compileSdkVersion 23
buildToolsVersion "23.0.3"
multiDexEnabled true
}
xinghuo {
versionCode getVersionCode()
versionName getVersionName()
minSdkVersion 16
targetSdkVersion 19
compileSdkVersion 23
buildToolsVersion "23.0.3"
}
}
...
}
最开始我看官方文档的要求,配置如下:
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
我在我自己的gradle文件中没有看到defaultConfig相关设置,于是就手动添加了改配置,运行却不成功。当时我一直不清楚问题出在哪里,后来尝试在不同变体中增加了该配置就可以了。如上图所示,我的工程有normal和xinghuo两个变体,我在normal的变体中增加multiDexEnabled true,即可成功编译。
- MultiDex.install(this)顺序写错
这个问题的出现还是由于我没有认真看官方文档,文档提到测试时
您也可以替换 AndroidJUnitRunner 中的 onCreate() 方法:
public void onCreate(Bundle arguments) {
MultiDex.install(getTargetContext());
super.onCreate(arguments);
...
}
然后我又结合别人的博客,说是可以重写attachBaseContext()方法。于是我就写出了如下代码:
@Override
protected void attachBaseContext(Context base) {
MultiDex.install(this);
super.attachBaseContext(base);
}
这个问题并不影响编译,当程序编译成功时,我别提有多高兴了。可是程序一运行就会崩溃…报错原因是java.lang.NoClassDefFoundError。
于是又开始疯狂百度,google查找原因,发现并不能解决我的问题,最后发现只有attachBaseContext方法中的顺序不一样,尽管不愿意相信,还是抱着试试看的态度修改了一下,这次是真的成功了。