Android - 使用MultiDex解决64K问题
目录
- 什么是64K
- 使用MultiDex解决64K
- 配置MultiDex
- productFlavors
一:什么是64K
问题描述
Error:The number of method references in a .dex file cannot exceed 64K.
Error:Execution failed for task ':app:transformClassesWithDexForRelease'.
即方法数目超过65535
二:使用MultiDex解决64K
Multidex支持到Android 5.0之前
安卓系统采用的是Dalvik虚拟机,采用的是JIT技术(Just-in-time compilation,即时编译,运行时编译DEX字节码文件,这也是以前为什么安卓手机用户总是诟病Android系统比iOS系统运行卡顿的原因),限制每个APK文件只能包含一个DEX文件(即classes.dex)。为了绕开这个限制,Google给我们提供了multidex support library兼容包,帮助我们实现应用程序加载多个DEX文件,并且这个兼容包作为程序的主DEX文件,管理者其他DEX文件的访问。
注意:由于Instant Run机制利用的就是multidex原理,当项目中minSdkVersion参数设置为20或者更小,并且运行在Android 4.4 (API level 20)或更低版本的设备中时,Instant Run将失效。
5.0之后
安卓系统改用了ART虚拟机(Android RunTime),采用的是OAT技术(Ahead-of-time,预编译,在应用安装的时候扫描应用中的所有DEX文件,并编译成一个.oat格式的文件供安卓设备执行,所以相比Dalvik虚拟机下的应用,安装时间较长)。因此可以理解为,使用ART虚拟机下的安卓系统自动支持APK文件中多个DEX的加载。
注意:使用Instant Run时,如果项目中的minSdkVersion参数设为21或更高版本,Android Studio编译运行时会自动使应用支持multidex。但Instant Run仅仅作用于debug版本,我们依然需要给release版本配置multidex来避开64K方法数的限制。
三:配置MultiDex
配置build.gradle
android {
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
配置AndroidManifest.xml
<?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 继承 MultiDexApplication
- 如果不想复写Application,在自己的写的继承Application的类中中添加方法
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this) ;
}
四:productFlavors
初次引入MultiDex 需要很长的时间,为减少开发阶段,运行时间,使用productFlavors
android {
//定义不同的flavors
productFlavors {
//开发阶段
dev {
//运行在Android 5.0以上版本的设备中,使用ART-supported格式生成multidex的速度要快得多
minSdkVersion 21
}
prod {
//实际支持的最低版本
minSdkVersion 14
}
}
}
写在最后
这个是一个解决方案,但是呢,我觉得,在写项目的时候,就要有意识去避免这么问题,不要过多的映入第三方,不同的依赖库就删了,还能较少包的体积,当然还有其他的解决方案,比如插件化,这个放在后面专门的讲