前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android 热修复】热修复原理 ( 类加载机制 | PathClassLoader 加载 Dex 机制 | PathDexList 查找 Class 机制 | 类查找的顺序机制 )

【Android 热修复】热修复原理 ( 类加载机制 | PathClassLoader 加载 Dex 机制 | PathDexList 查找 Class 机制 | 类查找的顺序机制 )

作者头像
韩曙亮
发布2023-03-29 09:39:56
1.1K0
发布2023-03-29 09:39:56
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、 PathClassLoader 加载 Dex 机制


Android 中 Class 加载机制 :

Java 代码运行时 , 使用 ClassLoader 加载 Class 字节码文件 , Class 字节码文件 , Jar 文件 , Dex 文件 , 都必须加载到内存中 ;

在 Android 平台中 , Android 应用运行时 , 使用 PathClassLoader 加载 Dex 文件 , 在应用启动时 , 首先将若干 Dex 文件加载到内存中 ;

一个 Android 应用中可以存在多个 Dex 文件 , 参考 【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList ) 博客 ,

二、 PathDexList 查找 Class 机制


当应用运行时调用到某类 A.class 时 , 会通过 PathClassLoader 加载该类 , PathClassLoader 是一个包装类 , 其中封装了 PathDexList 类 , 该类中的 Element[] dexElements 成员存放着多个 Dex 文件 ;

每个 Dex 文件中封装了多个 Class 字节码文件 ; 查找某个具体的 A.class 时 , 主要是通过 DexPathList 的 findClass 方法 , 遍历 Element[] dexElements 成员 ,

Element[] dexElements 数组中保存的就是内存中的 DEX 文件 , 如果 APP 中有

3

个 DEX 文件 , 那么该数组就有

3

个元素 ;

然后逐个遍历 获取该 element 中的 dexFile , 这是 DexFile 类型文件 ,

调用 DexFile 的 loadClassBinaryName 加载对应的 A.class 类 , 如果找到了 A.class 类 , 直接返回 ; 如果没有找到 , 则继续遍历下一个 Element[] dexElements 元素 ;

代码语言:javascript
复制
/*package*/ final class DexPathList {

    /**
     * dex/resource (class path) 元素集合.
     * 应该调用 pathElements , 但是 Facebook 应用通过反射修改 dexElements .
     */
    private final Element[] dexElements;
    
    public Class findClass(String name, List<Throwable> suppressed) {
        for (Element element : dexElements) {
            DexFile dex = element.dexFile;

            if (dex != null) {
                Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
                // 注意 : 这里如果查找到想要的类 , 直接返回 , 不会去向后遍历
                if (clazz != null) {
                    return clazz;
                }
            }
        }
        if (dexElementsSuppressedExceptions != null) {
            suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
        }
        return null;
    }
}

参考源码地址 : libcore/dalvik/src/main/java/dalvik/system/DexPathList.java

三、 类查找的顺序机制


在 PathDexList 查找 Class 中 , DexPathList 的 findClass 方法遍历 Element[] dexElements 数组永远都是从

0 索引开始 , 向后遍历 , 其中就隐含着 Dex 文件搜索的顺序机制 ;

顺序机制 : 如果在第 2 个 Dex 文件 和 第 3 个 Dex 文件中都包含该 A.class 字节码文件 , 则只会返回第 2 个 Dex 文件中的类 , 遍历到此处就返回了 , 不会去遍历到低 3 个 Dex 文件 ;

利用上述顺序加载的机制 , 将修复包的 dex 文件放在前面 , 就可以屏蔽后面出现问题的类 ;

示例 :

在已经发布的应用中 , 有 3 个 Dex 文件 , 其中第 2 个 Dex 文件中的 A.class 字节码类中出现了崩溃问题 , 这里我们将修复好的 A.class 文件打包成 Dex 文件 , 将其插入到原来第 1 个和第 2 个 Dex 文件之间 , 这样在类加载器加载 A.class 类时 , 按照顺序先把修复的 Dex 文件加载到内存中 , 不再向后查找第 3 个 Dex 文件中出现崩溃的 A.class 类了 ;

热修复只是在前面插入一个修复好的 Dex 文件 , 不会删除出现问题的 Dex 文件 ;

第 1 个 Dex 文件一定不能出现问题 , 如果出现问题 , 就无法在该 Dex 文件之气前插入 Dex 文件 , 这个主 Dex 文件中有 Application , MainActivity 等相关重要组件 , 无法进行替换 ;

如果第 1 个 Dex 文件出现问题 , 只能发布新版本 ;

实际上热修复机制属于一种利用漏洞的机制 , Google 没有正面支持该功能 , iOS 中就关闭了热修复功能 ;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、 PathClassLoader 加载 Dex 机制
  • 二、 PathDexList 查找 Class 机制
  • 三、 类查找的顺序机制
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档