Androdi热修复之路 —— 理解Multidex 分包原理

在早起的Android开发过程中,随着项目的增加开发者可能会遇到65535的问题,也就是程序中的方法达到上限,针对此问题官方给出的解决方案是Multidex,使用Multidex将程序中的代码打包成多个dex文件,从而让系统的避免方法上限的问题;

1、使用

  • 使用配置
  1. 在build.gradle中添加支持Multidex
defaultConfig{
   
  multiDexEnabled true  
}
  1. 添加Multidex依赖
implementation 'com.android.support:multidex:1.0.3'
  1. 在Application中初始化Multidex
MultiDex.install(this);
  1. 反编译打包后的APK查看生成的Dex中的类
    在这里插入图片描述
  2. 此时主classes.dex中的类
    在这里插入图片描述
  • 分包(配置主multiDex中的类)
  1. 在app目录下,创建MultiDex的配置文件multidex-config.txt
  2. 在配置文件中声明主Dex中的类
com/alex/kotlin/jniapplication/MainActivity.class
com/alex/kotlin/jniapplication/MainActivity2.class
  1. 在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) {
   }
    }
}
  1. 首先获取程序的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 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值