谈谈Android热修复

tech2024-03-16  59

 

概述

热修复成名已久,现在才开始谈确实有点晚了,不过没关系,这里给大家提供一个比较简单的思路。目的呢?算法帮助大家深入、或者复习“类加载”机制把,挺好玩的。

 

 

 

加载模型(双亲委派)

 

 

示意图

 

 

 

代理模式

android类加载采用的是双亲委派模式,就是会将请求先委托给父加载器进行处理,处理不了自己再处理。谈到委派,很容易想到“代理模式”,事实上对于ClassLoader而言,它与parent的关系确实是代理/委托关系,对被代理类进行访问控制(如果它已经加载过这个类,它将不会继续将请求委托给parent)。基于这个角度,它确实是代理模式。

 

 

 

 

装饰者模式

而对于parent ClassLoader而言,双亲委派也确实使它的能力增强了,例如DexClassLoader将使得类加载器具备从APK、DEX、JAR等文件加载class类等能力,如果基于这个角度考虑,它是装饰者模式。

 

 

 

双亲委派模式,即具有控制属性、又存在增加能力的行为。从表现上看,一般我们很难进行区分。事实上,我们使用设计模式也是为了解决某些问题,从这个角度来思考问题的话,我们来看下哪种设计模式,可以解决类加载的问题。考虑到类加载可能遇到的问题有哪些?

对系统class进行保护,防止核心类被串改防止重复加载

 

基于这两个问题点,我们发现类加载迫切需要解决的是访问控制,而不是能力增强。所以我们说双亲委派机制是一种代理模式。

 

 

 

加载过程

 

 

 

热修复

 

从上面的加载模型,我们了解到,类加载请求会优先交给parent处理。基于这个机制,我们只需要将自定义的ClassLoader插入到,APP的PathClassLoader的parent位置。这个将会对所有的类加载请求进行拦截。

 

 

上面代码其实会遇到一个问题,比如HomeActivity extends BaseActivity,我们对HomeActivity进行热修复,但是通过上面的加载会出现类找不到的异常。原因:对于HomeActivity被MyDexClassLoader加载,则它用到的所有未加载的类都将由该类加载器直接加载,针对这种情况由两种解决方案:

 

1、针对MyDexClassLoader加载的Class,通过反射重置classLoader

 

 

2、更改类加载模型

 

 

 

 

总结

整体流程比较简单,涉及到反射的点也不是很多,如果遇到android P及之后的版本反射失败的情况,可以使用元反射来进行处理。

最新回复(0)