美文网首页
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