安卓类加载机制和双亲委派机制

类加载机制

在安卓中提供了3个类加载器,BootClassLoader,PathClassLoader,DexClassLoader;双亲委派机制,是委培层级上的上下层级关系,并不是说3个类加载器有父子继承关系:

类加载的委派层级

BootClassLoader -> PathClassLoader -> DexClassLoader ;

类加载器的继承结构

BootClassLoader 是父类 , PathClassLoader / DexClassLoader 是 BootClassLoader 的子类 ;

① DexClassLoader 查询 :查询自己是否加载过 A ;

如果加载过则不需要再进行加载 ;

如果没有加载过 , 则向上级 PathClassLoader 询问 是否有加载过 A ;

② PathClassLoader 查询 :查询自己是否加载过 A ;

如果加载过则不需要再进行加载 ;

如果没有加载过 , 则向上级 BootClassLoader 询问 是否有加载过 A ;

③ BootClassLoader 查询 :查询自己是否加载过 A ;

如果加载过则不需要再进行加载 ;

如果没有加载过 , 则 查询自己是否可以加载 ;

④ BootClassLoader 查询是否可以加载 :

如果自己可以加载 A , 则自己加载 ;

如果自己不可以加载 A , 则将加载任务委派给下级 PathClassLoader ;

⑤ PathClassLoader 查询是否可以加载 :

如果自己可以加载 A , 则自己加载 ;

如果自己不可以加载 A , 则将加载任务 委派给下级 DexClassLoader ;

④ DexClassLoader 查询是否可以加载 :

如果自己可以加载 A , 则自己加载 ;

如果自己不可以加载 A , 则 抛出 Class Not Found 异常 ;

整个过程就是 从下到上 询问 , 然后 从上到下 委派 ;

双亲委派机制

类加载器层级

由高到低 : BootClassLoader -> PathClassLoader / DexClassLoader

什么是双亲委派

1.加载.class文件的时候,以递归的的形式逐级向上委托给父加载器ParentClassLoader去加载,如果加载过了,就不用在加载一遍2.如果父加载器也没加载过,则继续委托给父加载器去加载,一直到这条链路的顶级,顶级classLoader判断如果没加载过,则尝试加载,加载失败,则逐级向下交还调用者来加载.

双亲委派是如何实现的

任意一个classLoader对象都会有一个parent对象,我们下面的customClassLoader创建的时候虽然没有传递parent对象,但是在下面的ClassLoader类中的空参构造方法可以看出,会调用getSystemClassLoader()从而调用ClassLoader.createSystemClassLoader();,最后创建了一个PathClassLoader对象作为parent,而且在创建PathClassLoader的同时也指定了它的parent为BootClassLoader

ClassLoader customClassLoader= new ClassLoader() {

            @Override

            public Class<?> loadClass(String name) throws ClassNotFoundException {

                return super.loadClass(name);

            }

  };

public abstract class ClassLoader {

    static private class SystemClassLoader {

        public static ClassLoader loader = ClassLoader.createSystemClassLoader();

    }

    protected ClassLoader() {

        this(checkCreateClassLoader(), getSystemClassLoader());

    }

    protected ClassLoader(ClassLoader parent) {

        this(checkCreateClassLoader(), parent);

    }

    @CallerSensitive

    public static ClassLoader getSystemClassLoader() {

        return SystemClassLoader.loader;

    }

    private static ClassLoader createSystemClassLoader() {

        String classPath = System.getProperty("java.class.path", ".");

        String librarySearchPath = System.getProperty("java.library.path", "");

        //最终会调用PathClassLoader这个classLoader

        return new PathClassLoader(classPath, librarySearchPath, BootClassLoader.getInstance());

    }

    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{

            //1.先检查是否已经加载过--findLoaded

            Class<?> c = findLoadedClass(name);

            if (c == null) {

                try {

                    //2.如果自己没加载过,存在父类,则委托父类

                    if (parent != null) {

                        c = parent.loadClass(name, false);

                    } else {

                        c = findBootstrapClassOrNull(name);

                    }

                } catch (ClassNotFoundException e) {

                }

                if (c == null) {

                    //3.如果父类也没加载过,则尝试本级classLoader加载

                    c = findClass(name);

                }

            }

          return c;

    }

}

loadClass方法,对于任意一个classLoader对象来说,来加载文件的时候都会调用loadClass方法.

1.先检查自己是否已经加载过class文件了--用这个findLoadedClass方法,如果已经加载了直接返回就好了2.如果自己没加载过,存在父类,则委托父类去加载--用这个parent.loadClass(name, false)方法,此时就会向上传递,然后就会去父加载器中循环第1步,一直到顶级ClassLoader3.如果父类也没加载过,则尝试本级classLoader加载,如果加载失败了就会向下传递,交给调用方来实现.class文件的加载

双亲委派的作用

1.防止同一个.class文件重复加载

2.对于任意一个类确保在虚拟机中的唯一性.由加载它的类加载器和这个类的全类名一同确立其在Java虚拟机中的唯一性

3.保证.class文件不被篡改,通过委托方式可以保证系统类的加载逻辑不被篡改.

Android中的主要类加载器

1.PathClassLoader复杂的加载系统类和英勇程序的类,通常用来加载已安装apk的dex文件,实际上外部存储的dex文件也能加载

2.DexClassLoader可以加载dex文件以及包含dex的压缩文件(apk,dex,jar,zip)

3.BaseDexClassLoader实际应用层类文件的加载,而真正的加载逻辑委托给pathList来完成

4.BootClassLoaderAndroid平台上所有ClassLoader的最终parent,Android系统启动时会使用BootClassLoader来预加载常用类


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容