APP功能复杂,方法引用较多时,常常会出现一个编译错误,指明应用已经达到Android编译架构规定的引用限制,此限制到达的条件是APP及其引用库超过65536个方法。
一般出现的编译错误为:
trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.
或者是:
Conversion to Dalvik format failed:
Unable to execute dex: method ID not in [0, 0xffff]: 65536
这个错误里面的65536数字代表单个Dalvik Executable(DEX)字节码文件内的代码可调用的引用总数。
◆ ◆ ◆ ◆ ◆
要解决编译时出现的65536异常,有两个方向,一个是减少代码调用的引用总数、一个是引入多Dex文件支持。
>>>>
使用多Dex文件支持
多Dex文件支持功能针对minSdkVersion为21和更高的值与20和更低的值两种不同环境下有不同的配置方法。API级别>=21时,本身支持从APK加载多个DEX文件执行,ART在应用安装时执行预编译,扫描classesN.dex,编译合并成单个.oat文件供Android设备执行,不需要引入多Dex文件支持库。
01
如果minSdkVersion >= 21
只需要在模块级build.gradle文件中将multiDexEnabled设为true。
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 28
multiDexEnabled true
}
...
}
02
如果minSdkVersion <= 20
需要添加多Dex文件支持库。
-
修改模块级build.gradle文件启用多Dex支持,并增加依赖项
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 28
multiDexEnabled true
}
...
}
dependencies {
implementation 'com.android.support:multidex:1.0.3'
//使用androidx库则可用下面的配置方法
//implementation 'androidx.multidex:multidex:2.0.1'
}
-
Application替换或调用MultiDex.install启用多Dex文件支持
//下面方法三选一
//1. 替换应用Application为MultiDexApplication
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>
</manifest>
//2. 自定义Application类继承自MultiDexApplication并作为应用Application
public class MyApplication extends MultiDexApplication { ... }
//3. 不继承MultiDexApplication,在自定义Application中覆写attachBaseContext方法,增加MultiDex.install方法调用
public class MyApplication extends SomeOtherApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
>>>>
减少代码调用引用总数
-
检查应用的直接和传递依赖项
引入外部库时确保其引入的方法是必要的,不能仅仅为了使用几个方法而将一个非常庞大的库引入到引用中。这样做可以减少应用代码依赖项,规避DEX引用限制 -
通过ProGuard移除未使用的代码,进行代码压缩
使用代码混淆,移除未使用的类和方法,启动压缩确保交付的APP中不含有未使用的代码
注意:通过ProGuard进行代码优化时,需要注意不能将主DEX文件中启动期间需要的类优化掉,否则应用会崩溃并出现NoClassDefFoundError错误。
如果出现NoClassDefFoundError时,需要使用版本类型中的
multiDexKeepFile或multiDexKeepProguard属性来声明这些类,以手动将这些类指定为主要DEX文件中的必需类。
01
multiDexKeepFile使用方法
创建multidex-config.txt文件,内容为指定不需要混淆和压缩的类,保存后将其添加到build.gradle文件中。
//multidex-config.txt
com/example/MainActivity.class
com/example/MyClass.class
//build.gradle
android {
buildTypes {
release {
multiDexKeepFile file('multidex-config.txt')
...
}
}
}
02
multiDexKeepProguard使用方法
此方法使用与ProGuard文件使用语法一致,包含-keep选项,通过创建multidex-config.pro文件后,将其指定为ProGuard文件即可。
//multidex-config.pro
-keepclass com.example.MainActivity
-keep class com.example.MyClass
//build.gradle
android {
buildTypes {
release {
multiDexKeepProguard file('multidex-config.pro')
...
}
}
}
应用的调试过程中,需要配合两种方法来进行APP 多Dex文件优化,才能够保证APP正常、流畅运行。
- END -
本篇APP多Dex文件支持的使用方法与注意事项说明到这里就结束了,如果APP中有多Dex使用场景、65536编译失败问题等,可以参考此篇文档进行APP优化。
这里有更多科技咨询,新技术学习,关注我们,和我们一起成长!