Android之ClassLoader的工做机制

ClassLoader双亲代理模型加载类的特色及做用

JVM以及Dalvik均是经过ClassLoader加载类,其源码以下
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;
}
从源码分析可知loadClass方法先判断是否被loaded过,没有则经过parent加载,如此递归向上,称之位双亲委托。若是继承向上的路线中均没有被加载,才由当前ClassLoader负责加载。
特色:若某个类被根节点加载过,则在之后系统的整个生命周期内不会被从新加载。
做用:
    1.共享:Framework层级的类一旦被根节点加载就缓存在内存,之后不需从新加载。
    2.隔离:不一样继承路线上的classLoader加载的类确定不是同一个类,这样作可避免冒充核心库类,从而访问核心库包可见成员。例如,用户没法经过自定义java.lang.String类,来把系统的String类给替换掉。

Android应用中的ClassLoader对象

在Activity的onCreate方法中调用
ClassLoader classLoader = getClassLoader();
if (classLoader != null) {
lg.e("当前类对应的ClassLoader:" + classLoader.toString());
while (classLoader.getParent() != null) {
classLoader = classLoader.getParent();
lg.e("上个ClassLoader的父亲:" + classLoader.toString());
}
}
输出结果以下,

其中,BootClassLoader在系统启动时建立,PathClassLoader在应用启动时建立,用于加载/data/app/com.coca.androidunitylab-1.apk。所以在一个应用中至少有两个classLoader。


DexClassLoader与PathClassLoader的异同

适用场景:
     DexClassLoader能够加载jar/apk/dex,能够从SD卡中加载未安装的apk;
    PathClassLoader只能加载系统中已经安装过的apk;
二者的区别在于 optimizedDirectory参数,其在 BaseDexClassLoader构造方法中用于构建 DexPathList对象。
optimizedDirectory用来缓存须要加载的dex文件,并建立一个DexFile对象;若是它为null,那么会直接使用dex文件原有的路径来建立DexFile对象。 optimizedDirectory必须是内部存储路径 DexClassLoader因为能够指定 optimizedDirectory,从而能够加载外部dex,在使用的时候被复制到内部路径 optimizedDirectory内;而 PathClassLoader没指定 optimizedDirectory,所以只能加载内部dex文件(即已经安装的apk文件)。













相关文章
相关标签/搜索