zoukankan      html  css  js  c++  java
  • 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文件)。















  • 相关阅读:
    swfupload控件文件上传大小限制设置
    C# 判断和创建目录路径
    [转载]Python ImportError: No module named 'requests'解决方法
    使用SQL语句进行特定值排序
    使用SQL语句进行数据复制
    Email正则表达式验证
    c#winform程序的改名(修改名称)
    关于无法加载DLL"***.dll":找不到指定的模块(异常来自HRESULT:0x8007007E)问题的解决办法
    C#中倒计时汇总
    C#中倒计时
  • 原文地址:https://www.cnblogs.com/linux007/p/5782677.html
Copyright © 2011-2022 走看看