欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ClassLoader類(lèi)加載源碼解析

 更新時(shí)間:2019年09月16日 15:32:44   作者:droidDing  
這篇文章主要為大家詳細(xì)解析了ClassLoader類(lèi)加載源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Java類(lèi)加載器

1、BootClassLoader: 用于加載Android Framework層class文件。
2、PathClassLoader: 用于Android應(yīng)用程序類(lèi)加載器。可以加載指定的dex,jar、zip、zpk中的classes.dex
3、DexClassLoader:加載指定的dex,以及jar、zip、apk中的classes.dex

源碼解析

1.ClassLoader中提供loadClass用于加載指定類(lèi)

//ClassLoader.java
public Class<?> loadClass(String name) throws ClassNotFoundException {
 //該處調(diào)用了兩個(gè)參數(shù)的重載方法
  return loadClass(name, false);
 }
 
 protected Class<?> loadClass(String name, boolean resolve)
  throws ClassNotFoundException
 {
  //先查一下該類(lèi)是否已經(jīng)加載過(guò)了
   Class<?> c = findLoadedClass(name);
   if (c == null) {
    try {
     //雙親委托機(jī)制,先讓爸爸去找
     if (parent != null) {
      c = parent.loadClass(name, false);
     } else {
      //如果parent為null,則用BootClassLoader進(jìn)行加載
      c = findBootstrapClassOrNull(name);
     }
    } catch (ClassNotFoundException e) {
     // ClassNotFoundException thrown if class not found
     // from the non-null parent class loader
    }

    if (c == null) {
     //如果都找不到就自己去找,此方法在子類(lèi)BaseDexClassLoader類(lèi)中有重寫(xiě)
     c = findClass(name);
    }
   }
   return c;
 }

2.BaseDexClassLoader類(lèi)中對(duì)findClass有重寫(xiě),也是實(shí)際會(huì)使用執(zhí)行的

//BaseDexClassLoader.java
//查找class
 @Override
 protected Class<?> findClass(String name) throws ClassNotFoundException {
  ...
  //這里通過(guò)pathList變量來(lái)查找,而pathList是在BaseDexClassLoader的構(gòu)造方法中初始化的
  Class c = pathList.findClass(name, suppressedExceptions);
  ...
  return c;
 }
 
private final DexPathList pathList;
public BaseDexClassLoader(String dexPath, File optimizedDirectory,
   String librarySearchPath, ClassLoader parent, boolean isTrusted) {
  super(parent);
  //構(gòu)造方法中初始化pathList變量
  this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted);
 }

3.BaseDexClassLoader中是通過(guò)調(diào)用DexPathList中的findClass來(lái)實(shí)現(xiàn)的,那么接下來(lái)我們分析一下DexPathList是怎么實(shí)現(xiàn)的

//DexPathList.java
//是一個(gè)Element數(shù)組,一個(gè)element中包含一個(gè) DexFile,DexFile就代表一個(gè)Dex文件,里面的native(C/C++)函數(shù)來(lái)進(jìn)行Dex的加載工作
 private Element[] dexElements;
 
public Class<?> findClass(String name, List<Throwable> suppressed) {
  for (Element element : dexElements) {
   //此處調(diào)用Element的findClass來(lái)實(shí)現(xiàn),
   Class<?> clazz = element.findClass(name, definingContext, suppressed);
   if (clazz != null) {
    return clazz;
   }
  }
  return null;
 }
// Element為DexPathList的內(nèi)部類(lèi)
static class Element {
 private final File path;
  //一個(gè)DexFile就代表一個(gè)Dex文件
  private final DexFile dexFile;
  //有多個(gè)構(gòu)造方法,但都僅是將值傳過(guò)來(lái),讓Element來(lái)持有一個(gè)DexFile
  public Element(DexFile dexFile) {
 this.dexFile = dexFile;
   this.path = null;
 }
  
  public Class<?> findClass(String name, ClassLoader definingContext,
    List<Throwable> suppressed) {
    //通過(guò)DexFile來(lái)加載類(lèi)
   return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed)
     : null;
  }
 }

DexPathList(ClassLoader definingContext, String dexPath,
   String librarySearchPath, File optimizedDirectory, boolean isTrusted) {
   //通過(guò)makeDexElements方法為dexElements初始化
 this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,
           suppressedExceptions, definingContext, isTrusted);
}
//騰訊系的熱修復(fù),諸如微信tinker、qq空間qfix原理便是反射此方法,將修復(fù)后的類(lèi)打包成dex,通過(guò)反射該方法來(lái)將文件轉(zhuǎn)化為Element,并將新生成的element放到dexElements前面,這樣下次系統(tǒng)再去尋找某個(gè)class時(shí),會(huì)先從修復(fù)后的dex中來(lái)找class,找到后便不再繼續(xù)查找,從而修復(fù)該class,此方式便為插樁
private static Element[] makeDexElements(List<File> files, File optimizedDirectory,
   List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) {
  Element[] elements = new Element[files.size()];
  ...
  for (File file : files) {
 if (name.endsWith(DEX_SUFFIX)) {
    //以 .dex 結(jié)尾的
     // Raw dex file (not inside a zip/jar).
     //加載dex文件
      dex = loadDexFile(file, optimizedDirectory, loader, elements);
      if (dex != null) {
       elements[elementsPos++] = new Element(dex, null);
      }
    }
 }
   ...
  return elements;
 }

private static DexFile loadDexFile(File file, File optimizedDirectory, ClassLoader loader,
          Element[] elements)
   throws IOException {
  if (optimizedDirectory == null) {
   return new DexFile(file, loader, elements);
  } else {
   String optimizedPath = optimizedPathFor(file, optimizedDirectory);
   return DexFile.loadDex(file.getPath(), optimizedPath, 0, loader, elements);
  }
 }

4.這里通過(guò) new DexFile 或者 loadDex方法來(lái)創(chuàng)建DexFile,兩者類(lèi)似,那我們拿new DexFile 來(lái)舉例分析

//DexFile.java
private DexFile(String sourceName, String outputName, int flags, ClassLoader loader,
   DexPathList.Element[] elements) throws IOException {
  ...
  //此處調(diào)用openDexFile來(lái)實(shí)現(xiàn)
  mCookie = openDexFile(sourceName, outputName, flags, loader, elements);
  ...
 }

private static Object openDexFile(String sourceName, String outputName, int flags,
   ClassLoader loader, DexPathList.Element[] elements) throws IOException {
  //此處通過(guò)調(diào)用 openDexFileNative來(lái)實(shí)現(xiàn)
  return openDexFileNative(new File(sourceName).getAbsolutePath(),
         (outputName == null)
          ? null
          : new File(outputName).getAbsolutePath(),
         flags,
         loader,
         elements);
 }
//openDexFileNative是一個(gè)native方法,是由C/C++來(lái)實(shí)現(xiàn)的
private static native Object openDexFileNative(String sourceName, String outputName, int flags,
   ClassLoader loader, DexPathList.Element[] elements);

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringMVC框架REST架構(gòu)體系原理分析

    SpringMVC框架REST架構(gòu)體系原理分析

    REST:Representational State Transfer,資源表現(xiàn)層狀態(tài)轉(zhuǎn)換,是目前&#12112;較主流的&#12032;種互聯(lián)網(wǎng)軟件架構(gòu),它結(jié)構(gòu)清晰、標(biāo)準(zhǔn)規(guī)范、易于理解、便于擴(kuò)展
    2021-09-09
  • java實(shí)現(xiàn)通用分頁(yè)(后端)

    java實(shí)現(xiàn)通用分頁(yè)(后端)

    這篇文章主要介紹了java實(shí)現(xiàn)通用分頁(yè)(后端)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java類(lèi)的繼承實(shí)例詳解(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    Java類(lèi)的繼承實(shí)例詳解(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    在Java開(kāi)發(fā)中,我們常常用到繼承這一概念,可以說(shuō)繼承是Java這類(lèi)面向?qū)ο缶幊陶Z(yǔ)言的基石,今天小編一起和大家一起學(xué)習(xí)java類(lèi)的繼承
    2017-04-04
  • SpringBoot深入刨析數(shù)據(jù)層技術(shù)

    SpringBoot深入刨析數(shù)據(jù)層技術(shù)

    這篇文章主要介紹了SpringBoot數(shù)據(jù)層技術(shù)的解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • JavaI/O深入學(xué)習(xí)之輸入和輸出

    JavaI/O深入學(xué)習(xí)之輸入和輸出

    這篇文章主要介紹了JavaI/O深入學(xué)習(xí)之輸入和輸出,Java類(lèi)庫(kù)中的I/O類(lèi)分成輸入和輸出兩部分,可以在JDK文檔里的類(lèi)層次結(jié)構(gòu)中查看到。,需要的朋友可以參考下
    2019-06-06
  • springmvc常用注解標(biāo)簽詳解

    springmvc常用注解標(biāo)簽詳解

    本篇文章主要介紹了springmvc常用注解標(biāo)簽詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • java基于控制臺(tái)的學(xué)生學(xué)籍管理系統(tǒng)

    java基于控制臺(tái)的學(xué)生學(xué)籍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java基于控制臺(tái)的學(xué)生學(xué)籍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • SpringMVC中使用@PathVariable綁定路由中的數(shù)組的方法

    SpringMVC中使用@PathVariable綁定路由中的數(shù)組的方法

    這篇文章主要介紹了SpringMVC中使用@PathVariable綁定路由中的數(shù)組的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 深入講解Java Maven配置

    深入講解Java Maven配置

    這篇文章主要介紹了Maven的安裝配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10
  • 使用Idea maven創(chuàng)建Spring項(xiàng)目過(guò)程圖解

    使用Idea maven創(chuàng)建Spring項(xiàng)目過(guò)程圖解

    這篇文章主要介紹了使用Idea maven創(chuàng)建Spring項(xiàng)目過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02

最新評(píng)論