美文网首页
ClassLoader整理

ClassLoader整理

作者: 许方镇 | 来源:发表于2020-03-04 00:50 被阅读0次

Android中的ClassLoader是主要有

BootClassLoader:负责加载Android FrameWork层中的字节码文件;
PathClassLoader:负责加载已经安装到系统APK文件中的字节码文件;
DexClassLoader:负责加载指定目录中的字节码文件;

通俗点的话:
DexClassLoader用于加载非APK部分的dex。(比如热补丁生成的dex)
PathClassLoader用于apk中开发者开发的类或者依赖库。(比如开发自己写的xxxActivity和support包里的AppCompatActivity)
BootClassLoader用于加载系统的类。(比如系统的Activity)

继承关系:

DexClassLoader 和 PathClassLoader 是 BaseDexClassLoader的子类
BaseDexClassLoader 和 BootClassLoader是ClassLoader的子类
(BootClassLoader就在ClassLoader.java文件里)

image.png

parent和child关系

DexClassLoader 的 parent我们通常会设置为 PathClassLoader 。
PathClassLoader的 parent是 BootClassLoader

双亲委托

先看下ClassLoader的loadClass方法

    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
            // 首先检查类是否已经被加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        //parent不为空,则用parent的loadClass
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // 如果依旧没发现,则通过findClass去查找
                    c = findClass(name);
                }
            }
            return c;
    }

再看下DexClassLoader的findClass方法

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
        Class c = pathList.findClass(name, suppressedExceptions);
        if (c == null) {
            ClassNotFoundException cnfe = new ClassNotFoundException(
                    "Didn't find class \"" + name + "\" on path: " + pathList);
            for (Throwable t : suppressedExceptions) {
                cnfe.addSuppressed(t);
            }
            throw cnfe;
        }
        return c;
    }

去加载一个类的时候,首先查看该类是否被加载过,如果被加载过,则直接返回,如果没有则调用其父亲的加载类方法,同样查看其父亲是是否加载过,一直到顶层父亲都没有被加载过,则使用最顶层的父亲的findClass去加载,如果加载成功,则加入缓存中,如果不成功,则开始往回走,一直到最开始的加载类,调用其findClass方法去加载。

  1. 可以从缓存中获取,提高效率
  2. 加载一个类,需要先用最顶层的父类其加载,提高安全性。

相关文章

网友评论

      本文标题:ClassLoader整理

      本文链接:https://www.haomeiwen.com/subject/jxtcoctx.html