成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

了解 Android 類加載器的工作原理,DexPathList 在類加載過程中的作用

移動開發
Android的類加載器系統基于JVM的類加載器模型,但有一些特定的調整和優化,以適應Android平臺的需要。

類加載器

在Android中,類加載器(ClassLoader)是一個重要的組件,負責在運行時動態加載JVM和Android類庫。Android的類加載器系統基于JVM的類加載器模型,但有一些特定的調整和優化,以適應Android平臺的需要。

(1) Bootstrap ClassLoader:

  • 這是最頂層的類加載器,由JVM實現。
  • 主要加載Java和Android核心類庫。
  • 通常通過null作為父加載器。

(2) PathClassLoader(或DexClassLoader):

  • Android特有的類加載器,用于從APK文件、DEX文件或JAR/ZIP文件中加載類。
  • PathClassLoader是Android應用默認的類加載器,用于加載應用的類和資源。

DexClassLoader是PathClassLoader的一個子類,提供了從指定的路徑加載DEX文件的能力,動態加載插件或模塊化場景常用加載器。

//DexClassLoader.java
package dalvik.system;

public class DexClassLoader extends BaseDexClassLoader {
    public DexClassLoader(String dexPath, String optimizedDirectory,
            String libraryPath, ClassLoader parent) {
        super(dexPath, new File(optimizedDirectory), libraryPath, parent);
    }
    
    public DexClassLoader(String dexPath, String optimizedDirectory,
            String librarySearchPath, ClassLoader parent) {
        super(dexPath, null, librarySearchPath, parent);
    }
}

//PathClassLoader
package dalvik.system;

public class PathClassLoader extends BaseDexClassLoader {

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

可以發現PathClassLoader和DexClassLoader源碼很簡單,只包含了一個構造函數,去調用父類BaseDexClassLoader(所有的工作都應該是在BaseDexClassLoader里完成的了)。而這兩個加載器不同的是PathClassLoader的構造中少了optimizedDirectory這個參數,原因是PathClassLoader是加載/data/app中的apk,也就是系統中的apk,而這部分的apk都會解壓釋放dex到指定的目錄中,這個操作由系統完成,不需要單獨傳入路徑,而DexClassLoader傳入,用來緩存需要加載的dex文件,并創建一個DexFile對象,如果為null,會直接使用dex文件原有路徑創建DexFile(這個參數已經棄用,自API26起無效)。

(3) System ClassLoader(或AppClassLoader):

  • Android系統的應用類加載器,繼承自URLClassLoader。
  • 用于加載Android系統的類和應用的類。
  • 在Android中不直接引用System ClassLoader或AppClassLoader,通過ClassLoader.getSystemClassLoader()獲取。

(4) 自定義ClassLoader:

  • 可以繼承ClassLoader類或其子類(如DexClassLoader)來創建自定義的類加載器。
  • 自定義類加載器可以用于加載網絡上的類、從數據庫加載加密的類、或者實現更復雜的類加載邏輯。

類加載器的主要用途:

  • 動態加載和執行代碼,如插件化開發、熱更新等。
  • 加載和執行不同來源的代碼,如從網絡下載的JAR包或DEX文件。
  • 隔離不同來源的代碼,防止類沖突和安全問題。

注意:濫用類加載器可能導致內存泄漏和性能問題。在使用類加載器時,應該仔細考慮其生命周期和資源管理。

DexPathList

DexPathList是DexClassLoader和BaseDexClassLoader等類加載器用于處理DEX文件路徑的一個內部類。當使用DexClassLoader或BaseDexClassLoader加載DEX文件時,DexPathList起到了關鍵的作用。

(1) 作用:DexPathList負責管理和維護DEX文件的路徑信息,使類加載器能夠正確地找到并加載DEX文件中的類。

(2) 構造:DexPathList在DexClassLoader或BaseDexClassLoader的構造函數中被創建。構造DexPathList時,需要提供DEX文件的路徑、優化目錄、庫路徑以及父類加載器等參數。

public class BaseDexClassLoader extends ClassLoader {

    private final DexPathList pathList;
    
    public BaseDexClassLoader(String dexPath, File optimizedDirectory,
            String librarySearchPath, ClassLoader parent) {
        super(parent);
        this.pathList = new DexPathList(this, dexPath, librarySearchPath, optimizedDirectory);
    }
    
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
        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;
    }
}

(3) 成員變量:DexPathList有一個私有的final成員變量dexElements,是一個Element數組,包含了所有DEX文件的Element對象,每個Element對象對應一個DEX文件。

private final Element[] dexElements;

public DexPathList(ClassLoader definingContext, String dexPath,
        String libraryPath, File optimizedDirectory) {
    ...
    this.definingContext = definingContext;
    this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions);
    ...
}

(4) 加載DEX文件:在DexPathList的構造函數中,會調用makeDexElements()方法來加載DEX文件。這個方法會遍歷提供的DEX文件路徑列表,并為每個DEX文件創建一個Element對象,然后將這些Element對象添加到dexElements數組中。

private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory, ArrayList<IOException> suppressedExceptions) {
    // 1.創建Element集合
    ArrayList<Element> elements = new ArrayList<Element>();
    // 2.遍歷所有dex文件(也可能是jar、apk或zip文件)
    for (File file : files) {
        ZipFile zip = null;
        DexFile dex = null;
        String name = file.getName();
        ...
        // 如果是dex文件
        if (name.endsWith(DEX_SUFFIX)) {
            dex = loadDexFile(file, optimizedDirectory);

        // 如果是apk、jar、zip文件(這部分在不同的Android版本中,處理方式有細微差別)
        } else {
            zip = file;
            dex = loadDexFile(file, optimizedDirectory);
        }
        ...
        // 3.將dex文件或壓縮文件包裝成Element對象,并添加到Element集合中
        if ((zip != null) || (dex != null)) {
            elements.add(new Element(file, false, zip, dex));
        }
    }
    // 4.將Element集合轉成Element數組返回
    return elements.toArray(new Element[elements.size()]);
}

(5) 加載類:當類加載器需要加載一個類時,會通過DexPathList的loadClass()方法來實現。這個方法會遍歷dexElements數組中的每個Element對象,并嘗試從對應的DEX文件中加載類。一旦找到需要加載的類,就會返回該類的Class對象。

public Class findClass(String name, List<Throwable> suppressed) {
    for (Element element : dexElements) {
        // 遍歷出一個dex文件
        DexFile dex = element.dexFile;

        if (dex != null) {
            // 在dex文件中查找類名與name相同的類
            Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
            if (clazz != null) {
                return clazz;
            }
        }
    }
    if (dexElementsSuppressedExceptions != null) {
        suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
    }
    return null;
}

(6) 優化:為了提高性能,DexPathList還支持DEX文件的優化。在加載DEX文件時,可以將DEX文件優化到指定的目錄中,以減少內存占用和提高加載速度。

責任編輯:趙寧寧 來源: 沐雨花飛蝶
相關推薦

2025-06-26 03:33:00

2012-02-14 13:39:57

Java

2012-02-09 10:31:17

Java

2021-07-05 06:51:43

Java機制類加載器

2025-07-01 07:41:37

Java類加載器雙親委派

2019-12-09 15:08:30

JavaTomcatWeb

2024-03-12 07:44:53

JVM雙親委托機制類加載器

2024-12-04 09:01:55

引導類加載器C++

2024-03-08 08:26:25

類的加載Class文件Java

2010-03-16 14:58:15

Java類加載器

2012-11-06 10:19:18

Java自定義加載Java類

2023-05-10 11:07:18

2021-01-06 09:01:05

javaclass

2009-08-24 11:36:27

CLR加載過程

2024-12-02 09:01:23

Java虛擬機內存

2024-09-06 09:37:45

WebApp類加載器Web 應用

2024-04-09 08:41:41

JVM類加載Java

2019-07-24 08:34:35

Java對象數據結構

2009-02-03 09:42:53

JAVA類JVM指令forName方法

2021-07-28 10:08:19

類加載代碼塊面試
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人国产精品久久久 | 亚洲一区视频在线 | 婷婷精品 | 一区二区三区久久久 | av影音资源| 精品国产91亚洲一区二区三区www | av电影一区二区 | 狠狠操狠狠干 | 青娱乐国产 | 超碰精品在线 | av网址在线播放 | 欧美精品在线一区 | 毛片一区二区三区 | 国产激情综合五月久久 | 国产操操操 | 亚洲成人一区 | 欧美爱爱视频 | 九色视频网站 | 高清国产午夜精品久久久久久 | 精品综合网| 免费爱爱视频 | 好婷婷网| 99精品观看| 亚洲国产成人精品女人久久久 | 在线观看国产wwwa级羞羞视频 | www.色53色.com | 日日夜夜精品视频 | 99精品久久久久久 | 午夜欧美a级理论片915影院 | 亚州毛片 | 久草视 | jlzzjlzz国产精品久久 | 亚洲视频一 | 中文字幕av一区二区三区 | 黄片毛片免费看 | 九九热精品在线 | 亚洲天堂精品一区 | 亚洲一区二区在线播放 | 国产一区2区 | 国产精品色av | 曰韩一二三区 |