日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )

發布時間:2025/6/17 Android 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、65535 方法數限制和 MultiDex 配置
  • 二、多 DEX 加載引入
  • 三、PathClassLoader 類加載源碼分析
  • 四、BaseDexClassLoader 類加載源碼分析
  • 五、DexPathList 相關載源碼分析
  • 六、多 DEX 存放位置





一、65535 方法數限制和 MultiDex 配置



在 Android 開發中 , 尤其是項目比較大時 , 或引入的依賴庫過多 , 一般的項目后期都會遇到 如下問題 , 整個工程的方法數超過了 655356553565535 個 , 編譯時報如下錯誤 :

trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

Google 官方給出了解決方案 : https://developer.android.google.cn/studio/build/multidex.html


5.05.05.0 之前的版本 , 應用中只能使用單個 classes.dex , 5.05.05.0 及以后的版本 原生支持多個 classes.dex 文件 ;

如果最低版本號大于等于 212121 , 就可以不用配置 MultiDex ;

反之版本號小于 212121 , 則 必須進行 MultiDex 配置 ;


Google 提供的 com.android.support:multidex 庫 , 就是為了兼容 5.05.05.0 之前的版本 ;





二、多 DEX 加載引入



MultiDexApplication 中就使用 Android 中的類加載機制 , ClassLoader 加載機制 ;


ClassLoader 相關源碼在 libcore/dalvik/src/main/java/dalvik/system Android 源碼目錄下 ,

參考 : libcore/dalvik/src/main/java/dalvik/system


常用的 ClassLoader 是 PathClassLoaderDexClassLoader ;

PathClassLoader 只能加載 已安裝 apk 的 dex ;

DexClassLoader 可以加載 已安裝文件系統 中的 APK , DEX , JAR ;

源碼參考 :

  • PathClassLoader : libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
  • DexClassLoader : libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java




三、PathClassLoader 類加載源碼分析



在 Android 中使用的是 PathClassLoader , 該類很簡單 , 只是單純的繼承 BaseDexClassLoader ,

package dalvik.system;public class PathClassLoader extends BaseDexClassLoader {public PathClassLoader(String dexPath, ClassLoader parent) {super(dexPath, null, null, parent);}public PathClassLoader(String dexPath, String libraryPath,ClassLoader parent) {super(dexPath, null, libraryPath, parent);} }

參考源碼地址 : libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java





四、BaseDexClassLoader 類加載源碼分析



BaseDexClassLoader 是通過 Class<?> findClass(String name) 方法查找類的 , 給定一個全類名字符串 , 返回字節碼 ,

查找類通過調用 pathList 的 findClass 方法 , 獲取字節碼文件 ,

pathList 對應的成員變量定義是 DexPathList pathList , 它是 DexPathList 類型的 ,

public class BaseDexClassLoader extends ClassLoader {private final DexPathList pathList;@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





五、DexPathList 相關載源碼分析



DexPathList 的 findClass 方法 , 主要是遍歷 Element[] dexElements 成員 ,

Element[] dexElements 數組中保存的就是內存中的 DEX 文件 , 如果 APP 中有 333 個 DEX 文件 , 那么該數組就有 333 個元素 ;

然后 獲取該 element 中的 dexFile , 這是 DexFile 類型文件 ,

調用 DexFile 的 loadClassBinaryName 加載對應的類 ,

/*package*/ final class DexPathList {/*** dex/resource (class path) 元素集合.* 應該調用 pathElements , 但是 Facebook 應用通過反射修改 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





六、多 DEX 存放位置



上述 DexPathList 中的 Element[] dexElements 成員就保存了當前應用中的 DEX 文件 ,

再次回到 classes.dex 分割的問題上 , 如果我們設置一個主 DEX , 其中只存在代理 Application , 用于解密其它被加密的 DEX , 其它的 DEX 都是被加密的 ;

這些 DEX 文件 都需要被存放到上述 DexPathList 的 Element[] dexElements 數組中 ;

總結

以上是生活随笔為你收集整理的【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。