在早起的Android开发过程中,随着项目的增加开发者可能会遇到65535的问题,也就是程序中的方法达到上限,针对此问题官方给出的解决方案是Multidex,使用Multidex将程序中的代码打包成多个dex文件,从而让系统的避免方法上限的问题;
1、使用
- 使用配置
- 在build.gradle中添加支持Multidex
defaultConfig{
multiDexEnabled true
}
- 添加Multidex依赖
implementation 'com.android.support:multidex:1.0.3'
- 在Application中初始化Multidex
MultiDex.install(this);
- 反编译打包后的APK查看生成的Dex中的类
- 此时主classes.dex中的类
- 分包(配置主multiDex中的类)
- 在app目录下,创建MultiDex的配置文件multidex-config.txt
- 在配置文件中声明主Dex中的类
com/alex/kotlin/jniapplication/MainActivity.class
com/alex/kotlin/jniapplication/MainActivity2.class
- 在buildTypes中设置配置文件
multiDexKeepFile file('multidex-config.txt')
- 再次打包APK,反编译APK查看此时生成的Dex中的类
2、multiDex源码分析
在上面的使用过程中,体验了将Android一个项目打包到连个dex的过程,且可以设置配置文件制定主dex的类文件,因为主dex可能会影响到程序的启动问题,也是在启动时就加载到内存中的,那其他的dex是如何工作的呢?下面就从源码角度看看MultiDex如何完成其他dex加载的;
- MultiDex.install(this);
public static void install(Context context) {
if (IS_VM_MULTIDEX_CAPABLE) {
} else if (VERSION.SDK_INT < 4) {
//Multidex 最小支持版本SDK_INT 为 4
throw new RuntimeException("MultiDex installation failed. SDK " + VERSION.SDK_INT + " is unsupported. Min SDK version is " + 4 + ".");
} else {
try {
ApplicationInfo applicationInfo = getApplicationInfo(context); //获取程序的ApplicationInfo
//分别传入apk安装文件和apk的信息文件
doInstallation(context, new File(applicationInfo.sourceDir), new File(applicationInfo.dataDir), "secondary-dexes", "", true);
} catch (Exception var2) {
}
}
}
- 首先获取程序的ApplicationInfo并创建程序的sourceDir 和 dataDir 文件,调用doInstallation()加载文件信息,其中sourceDir为程序APK的安装目录,要被加载的dex文件就在此文件夹下,dataDir时解析apk目录下dex文件后的缓存目录,所有的dex文件都会被写入目录下
- doInstallation()
private static void doInstallation(Context mainContext, File sourceApk, File dataDir, String secondaryFolderName, String prefsKeyPrefix, boolean reinstallOnPatchRecoverableException) {
synchronized(installedApk) {
if (!installedApk.contains(sourceApk)) {
//判读此APk是否被加载过,加载过会自动跳过
installedApk.add(sourceApk); //静态集合保存被加载的apk
ClassLoader loader;
loader