ClassLoader

Java /Android 默认ClassLoader是PathClassLoader

Android 的 PathClassLoader 和DexClassLoader 都是BaseDexClassLoader的子类

BaseClassLoader是ClassLoader的子类,通过loadClass方法加载,Android将Java的ClassLoader简化了,第二个参数arg2 无效

loadClass 通过 findLoadedClass 方法进行查找,先查找缓存,缓存有就返回,否则就

查找父Loader,如果父加载器没有,就执行 findBootstrapClassOrNull()//空方法

如果都找不到就执行findClass找,自己加载

ClassLoader_第1张图片

缓存时独立共享的内存

ClassLoader_第2张图片从上往下加载

BaseDexClassLoader

findClass:

pathList = DexPathList

  @Override
203      protected Class findClass(String name) throws ClassNotFoundException {
204          // First, check whether the class is present in our shared libraries.
205          if (sharedLibraryLoaders != null) {
206              for (ClassLoader loader : sharedLibraryLoaders) {
207                  try {
208                      return loader.loadClass(name);
209                  } catch (ClassNotFoundException ignored) {
210                  }
211              }
212          }
213          // Check whether the class in question is present in the dexPath that
214          // this classloader operates on.
215          List suppressedExceptions = new ArrayList();
216          Class c = pathList.findClass(name, suppressedExceptions);
217          if (c == null) {
218              ClassNotFoundException cnfe = new ClassNotFoundException(
219                      "Didn't find class \"" + name + "\" on path: " + pathList);
220              for (Throwable t : suppressedExceptions) {
221                  cnfe.addSuppressed(t);
222              }
223              throw cnfe;
224          }
225          return c;
226      }

主要通过pathList.findClass(name,suppressedExecption) 查找

pathList.findClass

   public Class findClass(String name, List suppressed) {
531          for (Element element : dexElements) {
532              Class clazz = element.findClass(name, definingContext, suppressed);
533              if (clazz != null) {
534                  return clazz;
535              }
536          }
537  
538          if (dexElementsSuppressedExceptions != null) {
539              suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
540          }
541          return null;
542      }

通过Element.-dexFile.-loadClass-,defindClass-native

split()  -------- Unix系统分割使用 : ,Window使用 ;

new DexClassLoader时可以("path1:path2:path3:path4:path5:path6")

Element[] nakeDexElements(){

for(File file : files){

//添加

}

}

     private static Element[] makeDexElements(List files, File optimizedDirectory,
369              List suppressedExceptions, ClassLoader loader, boolean isTrusted) {
370        Element[] elements = new Element[files.size()];
371        int elementsPos = 0;
372        /*
373         * Open all files and load the (direct or contained) dex files up front.
374         */
375        for (File file : files) {
376            if (file.isDirectory()) {
377                // We support directories for looking up resources. Looking up resources in
378                // directories is useful for running libcore tests.
379                elements[elementsPos++] = new Element(file);
380            } else if (file.isFile()) {
381                String name = file.getName();
382  
383                DexFile dex = null;
384                if (name.endsWith(DEX_SUFFIX)) { //如果是.dex
385                    // Raw dex file (not inside a zip/jar).
386                    try {
387                        dex = loadDexFile(file, optimizedDirectory, loader, elements);
388                        if (dex != null) {
389                            elements[elementsPos++] = new Element(dex, null);
390                        }
391                    } catch (IOException suppressed) {
392                        System.logE("Unable to load dex file: " + file, suppressed);
393                        suppressedExceptions.add(suppressed);
394                    }
395                } else {
396                    try {
397                        dex = loadDexFile(file, optimizedDirectory, loader, elements);
398                    } catch (IOException suppressed) {
399                        /*
400                         * IOException might get thrown "legitimately" by the DexFile constructor if
401                         * the zip file turns out to be resource-only (that is, no classes.dex file
402                         * in it).
403                         * Let dex == null and hang on to the exception to add to the tea-leaves for
404                         * when findClass returns null.
405                         */
406                        suppressedExceptions.add(suppressed);
407                    }
408  
409                    if (dex == null) {
410                        elements[elementsPos++] = new Element(file);
411                    } else {
412                        elements[elementsPos++] = new Element(dex, file);
413                    }
414                }
415                if (dex != null && isTrusted) {
416                  dex.setTrusted();
417                }
418            } else {
419                System.logW("ClassLoader referenced unknown path: " + file);
420            }
421        }
422        if (elementsPos != elements.length) {
423            elements = Arrays.copyOf(elements, elementsPos);
424        }
425        return elements;
426      }
427  

OKHttp 下载文件

ClassLoader_第3张图片

自动打包补丁:

ClassLoader_第4张图片

还可以通过修改字节码实现热更新

你可能感兴趣的:(spring,java,后端)