1.ART双亲委托机制: PathClassLoader,DexClassLoader --继承自--> BaseDexClassLoader --继承自--> ClasssLoader protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class<?> c = findLoadedClass(name); //首次由本身自己去查询是否加载过 if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); //由父类去加载 } else { //若顶级类加载器父类是空 则调用这个方法 这个方法是又ClassLoader类提供的private方法,默认返回null c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { //如果父类加载器都加载为空 那么由本身去加载 // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } return c; } protected final Class<?> findLoadedClass(String name) { ClassLoader loader; if (this == BootClassLoader.getInstance()) loader = null; else loader = this; return VMClassLoader.findLoadedClass(loader, name); } //VMClassLoader.findLoadedClass是一个native方法,其实现在art/runtime/native/lava_lang_VMClassLoader: VMClassLoader_findLoadedClass方法 首次加载类 检察类是否加载过,如果加载过直接返回,由目标classLoader的父类去加载,加载成功直接返回, 加载失败则再次寻找父类的父类去加载,如果当前类是BootClassLoader则调用VMClassLoader.findLoadedClass去加载,成功则返回,失败则由原始目标classLoader的findClass去加载 BaseDexClassLoader -> findClass -> pathList.findClass() -> //DexPathList public Class<?> findClass(String name, List<Throwable> suppressed) { for (Element element : dexElements) { Class<?> clazz = element.findClass(name, definingContext, suppressed); if (clazz != null) { return clazz; } } if (dexElementsSuppressedExceptions != null) { suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions)); } return null; } 2.反射获取类中的dexElements (MutliDex插桩) 通过反射我们最终可以去修改DexPathList中的dexElements数组 -> BaseDexClassLoader:pathList(DexPathList):dexElements(Elements[]) 2.1.反射获取BaseDexClassLoader的成员变量pathList(DexPathList) 2.2.反射获取DexPathList的成员变量dexElements(Elements[]) 2.3.修改dexElements ()