ClassLoader原理剖析


Android 中 ClassLoader 种类

BootClassLoader

加载 Android FrameWork 层的class字节码文件

PathClassLoader

加载已经安装到系统中的apk 文件中的class 字节码文件

DexClassLoader

加载指定目录中的 class字节码文件

BaseClassLoader

是 PathClassLoader 和 DexClassLoader 的父类

Android 中 ClassLoader 的特点

  • 双亲代理模式的特点
  • 类加载的共享功能
  • 类加载的隔离功能

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;    }//空实现,交由子类去实现protected Class<?> findClass(String className) throws ClassNotFoundException {        throw new ClassNotFoundException(className);    }  // A class loader that loads classes from {@code .jar} and {@code .apk} files containing a {@code classes.dex} entry.//加载未安装到系统中的应用的类,动态加载的核心public class DexClassLoader extends BaseDexClassLoader {    public DexClassLoader(String dexPath, String optimizedDirectory,String libraryPath, ClassLoader parent) {       super(dexPath, new File(optimizedDirectory), libraryPath, parent);    }}//加载指定路径下的 class 文件 public class PathClassLoader extends BaseDexClassLoader {    public PathClassLoader(String dexPath, ClassLoader parent) {        super(dexPath, null, null, parent);    }    public PathClassLoader(String dexPath, String libraryPath,            ClassLoader parent) {        super(dexPath, null, libraryPath, parent);    }}public class BaseDexClassLoader extends ClassLoader {    private final DexPathList pathList;    public BaseDexClassLoader(String dexPath, File optimizedDirectory,            String libraryPath, ClassLoader parent) {        super(parent);        this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);    }    @Override    protected Class<?> findClass(String name) throws ClassNotFoundException {        List suppressedExceptions = new ArrayList();        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;    }    @Override    protected URL findResource(String name) {        return pathList.findResource(name);    }    @Override    protected Enumeration findResources(String name) {        return pathList.findResources(name);    }    @Override    public String findLibrary(String name) {        return pathList.findLibrary(name);    }    @Override    protected synchronized Package getPackage(String name) {        if (name != null && !name.isEmpty()) {            Package pack = super.getPackage(name);            if (pack == null) {                pack = definePackage(name, "Unknown", "0.0", "Unknown",                        "Unknown", "0.0", "Unknown", null);            }            return pack;        }        return null;    }    /**     * @hide     */    public String getLdLibraryPath() {        StringBuilder result = new StringBuilder();        for (File directory : pathList.getNativeLibraryDirectories()) {            if (result.length() > 0) {                result.append(':');            }            result.append(directory);        }        return result.toString();    }    @Override public String toString() {        return getClass().getName() + "[" + pathList + "]";    }}final class DexPathList {    private static final String DEX_SUFFIX = ".dex";    private static final String zipSeparator = "!/";    ...        public Class findClass(String name, List suppressed) {        for (Element element : dexElements) {            DexFile dex = element.dexFile;            if (dex != null) {                Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);                if (clazz != null) {                    return clazz;                }            }        }        if (dexElementsSuppressedExceptions != null) {            suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));        }        return null;    ...    }}

Android 中的动态加载难点

  • 有许多组件类需要注册后才能使用
  • 资源的动态加载很复杂
  • Android 程序运行需要一个上下文环境

更多相关文章

  1. android JNI入门 之helloworld
  2. Android(安卓)LoadingDialog一些问题
  3. Android中使用字体文件
  4. Android(安卓)解析strings.xml国际化
  5. android 目录下三种尺寸的 drawable 文件夹
  6. Android安装常见错误解决办法
  7. Android(安卓)Studio中的跨进程访问(aidl)
  8. Android手机开发ubuntu系统中常用的搜索命令
  9. android实现异步加载图片

随机推荐

  1. python粘包分析与解决
  2. 有关nginx Tornado tomcat apache
  3. Arcpy基础入门-5、读取自定义格式xml
  4. 我需要帮助完成这个生物信息学计划
  5. python的turtle模块画折线图
  6. python安装及写一个简单的验证码组件(配合
  7. Python 虚拟环境 windows平台 virtualenv
  8. 轮询Web服务的最佳方式(例如,对于Twitter应
  9. 生成使用AES包装的RSA私钥
  10. 整理python dict list set 增删改查