Android热修复之替换原有classes.dex的源代码分析

我们在服务端下载修复bug后的classes.dex并且动态替换原有的classes.dex这个过程的源代码的分析是我们今天要讨论的。

文末给出所有源码。


Context家族的classloader就是Android默认的加载器PathClassLoader。所以我们很简单一句话就可以获得了。

ClassLoader pathClassLoader = context.getClassLoader();

PathClassLoader只能加载已安装的apk,dex class loader则没有这个限制。所以我们需要创建一个dex class loader

ClassLoader classLoader = new DexClassLoader(patchFile.getAbsolutePath(),// dexPath
        oDexFile.getAbsolutePath(),// optimizedDirectory
        null,
        pathClassLoader
);

oDexFile.getAbsolutePath()是odex的路径,他相当于是classes.dex的helper,我们约定俗成在创建dex class loader需要传入他的路径。

patchFile.getAbsolutePath(),他就是我们的服务端传来的用于替换原来bug的dex的dex了。

这样声明以后,这个新的dex中所有的类,我们都可以通过dex class loader去访问了哦!!


然后我们就是分别获取PathClassLoader和dex class loader的element数组,然后把dex class loader的element插入到前者的某一位上即可。PathClassLoader中每一位都是一个dex,如果你不分包的话,他只有一个dex,所以我们想要热修复,自然是需要分包的。


我们看一下从classloader中获取element数组的方法

private static Object getDexElementByClassLoader(ClassLoader classLoader) throws Exception {
    Class<?> classLoaderClass = Class.forName("dalvik.system.BaseDexClassLoader");
    Field pathListField = classLoaderClass.getDeclaredField("pathList");
    pathListField.setAccessible(true);
    Object pathList = pathListField.get(classLoader);

    Class<?> pathListClass = pathList.getClass();
    Field dexElementsField = pathListClass.getDeclaredField("dexElements");
    dexElementsField.setAccessible(true);
    Object dexElements = dexElementsField.get(pathList);

    return dexElements;
}

我们用反射去拿到了classloader中的pathlist,再用反射去拿到pathlist中的element数组,就这么简单


我们看一下我们的dex class loader的element数组是怎么插入到前者的

private static Object combineArray(Object arrayLhs, Object arrayRhs) {
    Class<?> localClass = arrayLhs.getClass().getComponentType();
    int i = Array.getLength(arrayLhs);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值