EP30 HotFix分析

本文详细介绍了HotFix的工作原理和技术细节,包括如何通过制作包含修复代码的‘空’apk,在不重新安装应用的情况下进行代码更新。文章还深入探讨了HotFix的具体执行流程,如补丁包的加载与替换机制,以及类加载器的定制过程。

HotFix分析

这篇文章发出的时候,写HotFix的人已经看不到了。

大体步骤

HotFix的目的是在不重新安装apk的情况下做到代码的局部修改。
HotFix的大体执行步骤是这样的:

  • 制作一个「空」的apk,里面只包含要修复的代码所在的类;
  • 类中的要修改的方法打上注解;
  • 在应用程序入口的onCreate方法里,检查网络上有没有patch;
  • 检查完毕,调用PatchManagerfix方法开始替换打了注解的代码。

具体执行顺序

fix的执行步骤:

  1. 判断本地是否有补丁包,有就删掉,没有就加载

  2. 加载Dex用的是DexFile.loadDex方法。这个方法第一个参数是Jar or APK file with "classes.dex",包含classes.dex的jar或者apk;第二个参数是File that will hold the optimized form of the DEX data,优化后的dex文件;返回一个新的或者之前打开的DexFile。

  3. 然后新建一个新的classLoader,名为patchClassLoader,这个classloader使用当前context的classloader作为它的parent(双亲)(这样就把新加载的class跟当前的context关联起来了,关联在同一棵树上),并且覆写这个双亲的findClass方法。读过前面ClassLoader分析的朋友还记得吗,原本的findClass方法是在DexPathList.java中实现的,它遍历所有加载过的dex文件,用了native方法adClassBinaryName一个个试,看能不能加载到想要的类,返回找到的Class。覆写之后findClass的实现是这样的:

//the new overrided findClass() funciton

//patchDexFile是第二步中loadDex方法加载到的补丁包的DexFile
Class<?> clazz = patchDexFile.loadClass(className, this);
if (clazz == null
		&& className.startsWith("com.wangyin.payment")) {
	return Class.forName(className);
}
复制代码

patchDexFile是第2步中loadDex方法加载到的补丁包的DexFile,如果类名以com.wangyin.payment开头,那就返回这个Class。

  1. 利用patchDexFile.entries返回Enumeration<String>枚举类型的值,里面包含了patch中所有的class。然后,用第3步中新建的那个修改过双亲的findClass方法的classLoader来依次load patch中所有的class,step3中我们把findClass指定的寻找特征改成了com.wangyin.payment开头的类。
  2. 反射调用step4中找到的要修改的类中的run方法。(这个run方法干了什么,由于我没有补丁apk,所以也不太清楚。。)
//run方法是Patch接口里的空方法,参数是patchPath,补丁apk的位置
patchClazz.getMethod("run", String.class).invoke(
		patchClazz.newInstance(), patchPath);
复制代码
  1. 执行fixClass方法替换要修复的类。fixClass()利用注解,找到所有打了注解的方法,然后用fixMethod替换指定方法。
//fixClass
for (Method patchMethod : patchMethods) {
			isFixed = patchMethod.getAnnotation(Fixed.class);
			if (isFixed != null && isFixed.value()) {
				fixMethod(mainClassLoader, patchMethod);
			}
		}
复制代码

这个fixMethod最终调用so中的native方法replaceMethod来修复。

fixClass(patchClazz, mContext.getClassLoader());
复制代码

总结

主要还是对classLoader的理解。最终的修复用的是native方法。

Jan 3rd

转载于:https://juejin.im/post/5a31315b518825619a02af6b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值