1、Android中有哪几种ClassLoader?它们的作用和区别是什么?
Android系统ClassLoader包括三种分别是BootClassLoader、PathClassLoader和DexClassLoader。两个主要的Classloader,是PathClassLoader和DexClassLoader, 它们都继承自BaseDexClassLoader。
BootClassLoader主要用来预加载常用类。
PathClassLoader来加载系统类和主dex中的类
DexClassLoader则用于加载其他dex文件中的类
PathClassLoader、DexClassLoader区别:AndroidAPK可以有多个dex文件,一个主dex和N个子dex,后者专门用于加载子dex
2、简述ClassLoader的双亲委托模型
所谓双亲委托模式就是首先判断该Class是否已经加载,如果没有则不是自身去查找而是委托给父加载器进行查找,这样依次的进行递归,直到委托到最顶层的Bootstrap ClassLoader,如果Bootstrap ClassLoader找到了该Class,就会直接返回,如果没找到,则继续依次向下查找,如果还没找到则最后会交由自身去查找。
就像如下代码:
protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
Class<?> clazz = findLoadedClass(className);
if (clazz == null) {
ClassNotFoundException suppressed = null;
try {
clazz = parent.loadClass(className, false);
} catch (ClassNotFoundException e) {
suppressed = e;
}
if (clazz == null) {
try {
clazz = findClass(className);
} catch (ClassNotFoundException e) {
e.addSuppressed(suppressed);
throw e;
}
}
}
return clazz;
}
以上代码很简单,相信理解起来也比较容易
下面我们来看看双亲委托模式的两点好处:
- 避免重复加载,如果已经加载过一次Class,就不需要再次加载,而是先从缓存中直接读取。
- 更加安全,如果不使用双亲委托模式,就可以自定义一个String类来替代系统的String类,这显然会造成安全隐患,采用双亲委托模式会使得系统的String类在Java虚拟机启动时就被加载,也就无法自定义String类来替代系统的String类。
3、简述双亲委托模型在热修复领域的应用
刚刚我们说到DexClassLoader用于加载子dex,所以热修复主要原理就是利用他加载我们修复后的dex覆盖之前需要修复的类。
通过第二个问题我们知道了classloader不会重复加载,所以只需要让classLoader先加载我们dex里的类,就完成了覆盖的工作。而安卓的类加载器在加载一个类时会先从自身DexPathList对象中的Element数组中获取(Element[] dexElements)到对应的类,之后再加载。所以,我们只要让修复好的dex文件,放于Element数组的第一个元素,这样就能保证获取到的class是最新修复好的class了。
网友评论