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

了解 Android 類(lèi)加載器的工作原理,DexPathList 在類(lèi)加載過(guò)程中的作用

移動(dòng)開(kāi)發(fā)
Android的類(lèi)加載器系統(tǒng)基于JVM的類(lèi)加載器模型,但有一些特定的調(diào)整和優(yōu)化,以適應(yīng)Android平臺(tái)的需要。

類(lèi)加載器

在Android中,類(lèi)加載器(ClassLoader)是一個(gè)重要的組件,負(fù)責(zé)在運(yùn)行時(shí)動(dòng)態(tài)加載JVM和Android類(lèi)庫(kù)。Android的類(lèi)加載器系統(tǒng)基于JVM的類(lèi)加載器模型,但有一些特定的調(diào)整和優(yōu)化,以適應(yīng)Android平臺(tái)的需要。

(1) Bootstrap ClassLoader:

  • 這是最頂層的類(lèi)加載器,由JVM實(shí)現(xiàn)。
  • 主要加載Java和Android核心類(lèi)庫(kù)。
  • 通常通過(guò)null作為父加載器。

(2) PathClassLoader(或DexClassLoader):

  • Android特有的類(lèi)加載器,用于從APK文件、DEX文件或JAR/ZIP文件中加載類(lèi)。
  • PathClassLoader是Android應(yīng)用默認(rèn)的類(lèi)加載器,用于加載應(yīng)用的類(lèi)和資源。

DexClassLoader是PathClassLoader的一個(gè)子類(lèi),提供了從指定的路徑加載DEX文件的能力,動(dòng)態(tài)加載插件或模塊化場(chǎng)景常用加載器。

//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);
    }
}

可以發(fā)現(xiàn)PathClassLoader和DexClassLoader源碼很簡(jiǎn)單,只包含了一個(gè)構(gòu)造函數(shù),去調(diào)用父類(lèi)BaseDexClassLoader(所有的工作都應(yīng)該是在BaseDexClassLoader里完成的了)。而這兩個(gè)加載器不同的是PathClassLoader的構(gòu)造中少了optimizedDirectory這個(gè)參數(shù),原因是PathClassLoader是加載/data/app中的apk,也就是系統(tǒng)中的apk,而這部分的apk都會(huì)解壓釋放dex到指定的目錄中,這個(gè)操作由系統(tǒng)完成,不需要單獨(dú)傳入路徑,而DexClassLoader傳入,用來(lái)緩存需要加載的dex文件,并創(chuàng)建一個(gè)DexFile對(duì)象,如果為null,會(huì)直接使用dex文件原有路徑創(chuàng)建DexFile(這個(gè)參數(shù)已經(jīng)棄用,自API26起無(wú)效)。

(3) System ClassLoader(或AppClassLoader):

  • Android系統(tǒng)的應(yīng)用類(lèi)加載器,繼承自URLClassLoader。
  • 用于加載Android系統(tǒng)的類(lèi)和應(yīng)用的類(lèi)。
  • 在Android中不直接引用System ClassLoader或AppClassLoader,通過(guò)ClassLoader.getSystemClassLoader()獲取。

(4) 自定義ClassLoader:

  • 可以繼承ClassLoader類(lèi)或其子類(lèi)(如DexClassLoader)來(lái)創(chuàng)建自定義的類(lèi)加載器。
  • 自定義類(lèi)加載器可以用于加載網(wǎng)絡(luò)上的類(lèi)、從數(shù)據(jù)庫(kù)加載加密的類(lèi)、或者實(shí)現(xiàn)更復(fù)雜的類(lèi)加載邏輯。

類(lèi)加載器的主要用途:

  • 動(dòng)態(tài)加載和執(zhí)行代碼,如插件化開(kāi)發(fā)、熱更新等。
  • 加載和執(zhí)行不同來(lái)源的代碼,如從網(wǎng)絡(luò)下載的JAR包或DEX文件。
  • 隔離不同來(lái)源的代碼,防止類(lèi)沖突和安全問(wèn)題。

注意:濫用類(lèi)加載器可能導(dǎo)致內(nèi)存泄漏和性能問(wèn)題。在使用類(lèi)加載器時(shí),應(yīng)該仔細(xì)考慮其生命周期和資源管理。

DexPathList

DexPathList是DexClassLoader和BaseDexClassLoader等類(lèi)加載器用于處理DEX文件路徑的一個(gè)內(nèi)部類(lèi)。當(dāng)使用DexClassLoader或BaseDexClassLoader加載DEX文件時(shí),DexPathList起到了關(guān)鍵的作用。

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

(2) 構(gòu)造:DexPathList在DexClassLoader或BaseDexClassLoader的構(gòu)造函數(shù)中被創(chuàng)建。構(gòu)造DexPathList時(shí),需要提供DEX文件的路徑、優(yōu)化目錄、庫(kù)路徑以及父類(lèi)加載器等參數(shù)。

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有一個(gè)私有的final成員變量dexElements,是一個(gè)Element數(shù)組,包含了所有DEX文件的Element對(duì)象,每個(gè)Element對(duì)象對(duì)應(yīng)一個(gè)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的構(gòu)造函數(shù)中,會(huì)調(diào)用makeDexElements()方法來(lái)加載DEX文件。這個(gè)方法會(huì)遍歷提供的DEX文件路徑列表,并為每個(gè)DEX文件創(chuàng)建一個(gè)Element對(duì)象,然后將這些Element對(duì)象添加到dexElements數(shù)組中。

private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory, ArrayList<IOException> suppressedExceptions) {
    // 1.創(chuàng)建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版本中,處理方式有細(xì)微差別)
        } else {
            zip = file;
            dex = loadDexFile(file, optimizedDirectory);
        }
        ...
        // 3.將dex文件或壓縮文件包裝成Element對(duì)象,并添加到Element集合中
        if ((zip != null) || (dex != null)) {
            elements.add(new Element(file, false, zip, dex));
        }
    }
    // 4.將Element集合轉(zhuǎn)成Element數(shù)組返回
    return elements.toArray(new Element[elements.size()]);
}

(5) 加載類(lèi):當(dāng)類(lèi)加載器需要加載一個(gè)類(lèi)時(shí),會(huì)通過(guò)DexPathList的loadClass()方法來(lái)實(shí)現(xiàn)。這個(gè)方法會(huì)遍歷dexElements數(shù)組中的每個(gè)Element對(duì)象,并嘗試從對(duì)應(yīng)的DEX文件中加載類(lèi)。一旦找到需要加載的類(lèi),就會(huì)返回該類(lèi)的Class對(duì)象。

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

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

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

責(zé)任編輯:趙寧寧 來(lái)源: 沐雨花飛蝶
相關(guān)推薦

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機(jī)制類(lèi)加載器

2024-03-12 07:44:53

JVM雙親委托機(jī)制類(lèi)加載器

2019-12-09 15:08:30

JavaTomcatWeb

2024-12-04 09:01:55

引導(dǎo)類(lèi)加載器C++

2024-03-08 08:26:25

類(lèi)的加載Class文件Java

2012-11-06 10:19:18

Java自定義加載Java類(lèi)

2010-03-16 14:58:15

Java類(lèi)加載器

2023-05-10 11:07:18

2021-01-06 09:01:05

類(lèi)javaclass

2024-12-02 09:01:23

Java虛擬機(jī)內(nèi)存

2009-08-24 11:36:27

CLR加載過(guò)程

2024-04-09 08:41:41

JVM類(lèi)加載Java

2019-07-24 08:34:35

Java對(duì)象數(shù)據(jù)結(jié)構(gòu)

2024-09-06 09:37:45

WebApp類(lèi)加載器Web 應(yīng)用

2021-07-28 10:08:19

類(lèi)加載代碼塊面試

2009-02-03 09:42:53

JAVA類(lèi)JVM指令forName方法

2024-03-28 12:32:18

JVM類(lèi)加載構(gòu)造器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 精品视频一区二区三区四区 | 99久久成人 | hdfreexxxx中国妞 | 欧美精品日韩 | 亚洲三级在线观看 | av一区在线观看 | 欧美视频精品 | 久久久久国产一区二区三区四区 | 欧美日产国产成人免费图片 | 色天天综合 | 国产精品国产成人国产三级 | www.色.com| 精品在线看 | 久久久精彩视频 | 成人午夜黄色 | 国产91在线播放 | 99精品国产一区二区三区 | 久久久精品一区 | 久久久久亚洲 | 一区二区三区精品在线视频 | 97视频久久| 国产精品久久久久久 | 色先锋影音 | 视频一区中文字幕 | 亚洲一区二区黄 | 天天躁日日躁狠狠很躁 | 97人人超碰 | 99热精品在线 | 91免费在线播放 | 亚洲一区精品视频 | 亚洲一区二区三区在线视频 | 国产精品毛片在线 | 亚洲精品乱码久久久久久按摩 | 在线国产小视频 | 国产成人精品在线播放 | 日韩欧美中文 | 亚洲一区二区三区 | 亚洲第一区国产精品 | 亚洲视频在线观看免费 | 91在线第一页 | 一区二区视频在线 |