【Android 热修复】热修复原理 ( 类加载分析 | 分析 PathClassLoader 源码 | 分析 BaseDexClassLoader 源码 | 分析 PathDexList 源码 )
文章目錄
- 一、分析 PathClassLoader 源碼
- 二、分析 BaseDexClassLoader 源碼
- 三、分析 PathDexList 源碼
- 四、 源碼資源
一、分析 PathClassLoader 源碼
PathClassLoader 是 Android 平臺的類加載器 , 繼承了 BaseDexClassLoader ;
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);} }源碼路徑 : libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
二、分析 BaseDexClassLoader 源碼
BaseDexClassLoader 中的 findClass 方法 , 就是查找字節(jié)碼類的核心方法 ;
BaseDexClassLoader 的 protected Class<?> findClass(String name) 是 protected 屬性的 , 不能直接調(diào)用 , 需要通過反射才能調(diào)用 ;
應(yīng)用調(diào)用所有的類的入口 , 就是該函數(shù) , 所有 Java 類都是通過該類進行查找的 ;
BaseDexClassLoader 中的 findClass 方法分析 : 傳入查找的類名 name 后 , 會調(diào)用 DexPathList pathList 成員的額 findClass 方法 ;
public class BaseDexClassLoader extends ClassLoader {/*** Hook for customizing how dex files loads are reported.** This enables the framework to monitor the use of dex files. The* goal is to simplify the mechanism for optimizing foreign dex files and* enable further optimizations of secondary dex files.** The reporting happens only when new instances of BaseDexClassLoader* are constructed and will be active only after this field is set with* {@link BaseDexClassLoader#setReporter}.*//* @NonNull */ private static volatile Reporter reporter = null;private final DexPathList pathList;public BaseDexClassLoader(ByteBuffer[] dexFiles, ClassLoader parent) {// TODO We should support giving this a library search path maybe.super(parent);this.pathList = new DexPathList(this, dexFiles);}@Overrideprotected 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;} }源碼路徑 : libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
三、分析 PathDexList 源碼
應(yīng)用調(diào)用類 A.java 時 , 通過 PathClassLoader 調(diào)用 , PathClassLoader 沒有實際內(nèi)容 , 只是繼承 BaseDexClassLoader , 主要靠 BaseDexClassLoader 的 findClass 方法查找 A.class 文件 , BaseDexClassLoader 又調(diào)用 DexPathList pathList 成員的 findClass 方法 , 查找 A.class 文件 ;
當(dāng)應(yīng)用運行時調(diào)用到某類 A.class 時 , 會通過 PathClassLoader 加載該類 , PathClassLoader 是一個包裝類 , 其中封裝了 PathDexList 類 , 該類中的 Element[] dexElements 成員存放著多個 Dex 文件 ;
每個 Dex 文件中封裝了多個 Class 字節(jié)碼文件 ; 查找某個具體的 A.class 時 , 主要是通過 DexPathList 的 findClass 方法 , 遍歷 Element[] dexElements 成員 ,
Element[] dexElements 數(shù)組中保存的就是內(nèi)存中的 DEX 文件 , 如果 APP 中有 333 個 DEX 文件 , 那么該數(shù)組就有 333 個元素 ;
然后逐個遍歷 獲取該 element 中的 dexFile , 這是 DexFile 類型文件 ,
調(diào)用 DexFile 的 loadClassBinaryName 加載對應(yīng)的 A.class 類 , 如果找到了 A.class 類 , 直接返回 ; 如果沒有找到 , 則繼續(xù)遍歷下一個 Element[] dexElements 元素 ;
/*package*/ final class DexPathList {/*** dex/resource (class path) 元素集合.* 應(yīng)該調(diào)用 pathElements , 但是 Facebook 應(yīng)用通過反射修改 dexElements .*/private final Element[] dexElements;public Class findClass(String name, List<Throwable> suppressed) {for (Element element : dexElements) {DexFile dex = element.dexFile;if (dex != null) {Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);// 注意 : 這里如果查找到想要的類 , 直接返回 , 不會去向后遍歷if (clazz != null) {return clazz;}}}if (dexElementsSuppressedExceptions != null) {suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));}return null;} }
參考源碼地址 : libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
四、 源碼資源
源碼資源 :
- GitHub 地址 : https://github.com/han1202012/HotFix
- CSDN 源碼快照 : https://download.csdn.net/download/han1202012/16651312
總結(jié)
以上是生活随笔為你收集整理的【Android 热修复】热修复原理 ( 类加载分析 | 分析 PathClassLoader 源码 | 分析 BaseDexClassLoader 源码 | 分析 PathDexList 源码 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 热修复】热修复原理 (
- 下一篇: 【Android 热修复】热修复原理 (