Android-Multidex安装流程解析

本文详细解析了Android Multidex的安装流程,包括Multidex安装的步骤,如检查VM支持、删除旧副dex目录、提取zip文件并返回列表、修改pathList等。重点分析了提取zip文件的操作和修改pathList的过程。
摘要由CSDN通过智能技术生成

Android-Multidex安装流程解析

关于为什么需要引入Multidex支持以及如何配置Multidex可参考官网,本篇不做阐述,本篇着重分析Multidex1.0.2源码进行分析

大家都知道配置Multidex都需要在Application中的添加这样代码

public class MyApplication extends SomeOtherApplication {
   
  @Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(context);
     Multidex.install(this);
  }
}

其关键代码是Multidex类的install方法,我们来看看内部如何实现

public final class MultiDex {
   
    static final String TAG = "MultiDex";
    private static final Set<File> installedApk = new HashSet();
    private static final boolean IS_VM_MULTIDEX_CAPABLE = isVMMultidexCapable(System.getProperty("java.vm.version"));
    ...
    private MultiDex() {
    }

    public static void install(Context context) {
        Log.i("MultiDex", "Installing application");
        //1、判断虚拟机是否支持MultiDex
        if(IS_VM_MULTIDEX_CAPABLE) {
            Log.i("MultiDex", "VM has multidex support, MultiDex support library is disabled.");
        } else if(VERSION.SDK_INT < 4) {
            //2、Android SDK小于4不支持Multidex
            throw new RuntimeException("MultiDex installation failed. SDK " + VERSION.SDK_INT + " is unsupported. Min SDK version is " + 4 + ".");
        } else {
            try {
                ApplicationInfo applicationInfo = getApplicationInfo(context);
                if(applicationInfo == null) {
                    Log.i("MultiDex", "No ApplicationInfo available, i.e. running on a test Context: MultiDex support library is disabled.");
                    return;
                }
                //3、关键代码
                doInstallation(context, new File(applicationInfo.sourceDir), new File(applicationInfo.dataDir), "secondary-dexes", "");
            } catch (Exception var2) {
                Log.e("MultiDex", "MultiDex installation failure", var2);
                throw new RuntimeException("MultiDex installation failed (" + var2.getMessage() + ").");
            }

            Log.i("MultiDex", "install done");
        }
    }
    static boolean isVMMultidexCapable(String versionString) {
        boolean isMultidexCapable = false;
        if(versionString != null) {
            Matcher matcher = Pattern.compile("(\\d+)\\.(\\d+)(\\.\\d+)?").matcher(versionString);
            if(matcher.matches()) {
                try {
                    int major = Integer.parseInt(matcher.group(1));
                    int minor = Integer.parseInt(matcher.group(2));
                    isMultidexCapable = major > 2 || major == 2 && minor >= 1;
                } catch (NumberFormatException var5) {
                    ;
                }
            }
        }

        Log.i("MultiDex", "VM with version " + versionString + (isMultidexCapable?" has multidex support":" does not have multidex support"));
        return isMultidexCapable;
    }
}

小结:Multidex.install方法可分为如下3步
1、判断VM是否原生支持Multidex,如果支持就不进行Multidex.install方法
2、如果Android SDK小于4,直接抛出异常提示不支持Multidex
3、也是最关键的代码即doInstallation方法


继续看doInstallation方法

private static void doInstallation(Context mainContext, File sourceApk, File dataDir, String secondaryFolderName, String prefsKeyPrefix) throws IOException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
        //installedApk是个全局静态变量Set集合
        Set var5 = installedApk;
        synchronized(installedApk) {
            if(!installedApk.contains(sourceApk)) {

                //1、如果集合中不存在将souceApk文件加入其中
                installedApk.add(sourceApk);

                //Android5.0以及以上版本使用ART机制运行,后者原生支持从 APK 文件加载多个 DEX 文件
                if(VERSION.SDK_INT > 20) {
                    Log.w("MultiDex", "MultiDex is not guaranteed to work in SDK version " + VERSION.SDK_INT + ": SDK version higher than " + 20 + " should be backed by " + "runtime with built-in multidex capabilty but it's not the " + "case here: java.vm.version=\"" + System.getProperty("java.vm.version") + "\"");
                }

                ClassLoader loader;
                try {
                    //此处获取的类型为PathClassLoader,后面安装非主dex会使用到
                    loader = mainContext.g
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值