第十周:classLoader for Android

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;
}

以上代码很简单,相信理解起来也比较容易
下面我们来看看双亲委托模式的两点好处:

  1. 避免重复加载,如果已经加载过一次Class,就不需要再次加载,而是先从缓存中直接读取。
  2. 更加安全,如果不使用双亲委托模式,就可以自定义一个String类来替代系统的String类,这显然会造成安全隐患,采用双亲委托模式会使得系统的String类在Java虚拟机启动时就被加载,也就无法自定义String类来替代系统的String类。

3、简述双亲委托模型在热修复领域的应用

刚刚我们说到DexClassLoader用于加载子dex,所以热修复主要原理就是利用他加载我们修复后的dex覆盖之前需要修复的类。

通过第二个问题我们知道了classloader不会重复加载,所以只需要让classLoader先加载我们dex里的类,就完成了覆盖的工作。而安卓的类加载器在加载一个类时会先从自身DexPathList对象中的Element数组中获取(Element[] dexElements)到对应的类,之后再加载。所以,我们只要让修复好的dex文件,放于Element数组的第一个元素,这样就能保证获取到的class是最新修复好的class了。

你可能感兴趣的:(第十周:classLoader for Android)