类的加载(doing)

2018-12-12  本文已影响0人  Wi1ls努力努力再努力

双亲委派模型

loadClass(String,boolean)@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;
}

-⑴查找本加载器是否已经加载过这个 class


ClassLoader.java

protected ClassLoader(){
  this(getSystemClassLoader(), false);
}

protected ClassLoader(ClassLoader parentLoader){
  this(parentLoader, false);
}

ClassLoader(ClassLoader parentLoader, boolean nullAllowed){
  if(parentLoader == null && !nullAllowed){
      threow new NullPointerException("parentLoader == null && !nullAllowed);
  }
  parent = parentLoader;
}

pubic static ClassLoader getSystemClassLoader(){
  return SystemClassLoader.loader;
}

static private class SystemClassLoader{
  public static ClassLoader loader = ClassLoader.createSystemClassLoader();
}

private static ClassLoader createSystemClassLoader(){
  String classPath = System.getProperty("java.class.path",".");
   
  return new PathClassLoader(classPath,BootClassLoader.getInstance());
}

PathClassLoader 和 DexClassLoader 继承自 BaseDexClassLoader,其主要逻辑都在 BaseDexClassLoader,不同点在于构造函数传入的参数。

DexClassLoader

public DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent){
  super(dexPath, new File(optimizedDirectory), libraryPath, parent);
}

PathClassLoader

public PathClassLoader(String dexPath, ClassLoader parent){
  super(dexPath, null, null, parent);
}

public PathClassLoader(String dexPath, String libraryPath, ClassLoader parent){
  super(dexPath, null, library, parent);
}

BaseDexClassLoader

/**
     * Constructs an instance.
     *
     * @param dexPath the list of jar/apk files containing classes and
     * resources, delimited by {@code File.pathSeparator}, which
     * defaults to {@code ":"} on Android
     * @param optimizedDirectory directory where optimized dex files
     * should be written; may be {@code null}
     * @param libraryPath the list of directories containing native
     * libraries, delimited by {@code File.pathSeparator}; may be
     * {@code null}
     * @param parent the parent class loader
     */
public BaseDexClassLoader(String dexPath, File optimizedDirectory, String libraryPath, ClassLoader parent){
    super(parent);
    this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
}

findClass(String)@BaseDexClassLoader.java

protected Class<?> findClass(String name) throws ClassNotFoundException{
  List<Throwable> suppressedExceptions = new ArrayList<Throwable>( );
  Class c = pathList.findClass(name, suppressedExceptions);
  return c;
}

上述的 pathList 在构造函数中实例化,是 DexPathList 对象

DexPathList

public DexPathList(ClassLoader definingContext, String dexPath, String libraryPath, File optimizedDirectory){
  ...
  this.definingContext = definingContext;
  this.dexElements = makePathElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions);
  this.nativeLibraryDirectories = splitPaths(libraryPath, false);
  this.systemNativeLibraryDirectories = splitPaths(System.getProperty("java.library.path"), true);
  this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null, suppressedExctprions);
}

public Class findClass(String name, List<Throwable> suppressed){
  for(Element element : dexElements){
    DexFile dex = element.dexFile;

    Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
    return clazz;
  }
}

DexFile.java

public Class loadClassBinaryName(String name, ClassLoader loader, List<Throwable> suppressed){
  return defineClass(name, loader, mCookie, suppressed);
}

private static Class defineClass(String name, ClassLoader loader, Object cookie, List<Throwable> suppressed){
  Class result = defineClassNamtive(name, loader, cookie);
}
上一篇下一篇

猜你喜欢

热点阅读