Android 8.0 (Oreo API 25) 系统中创建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList { private Element[] dexElements; public DexPathList(ClassLoader definingContext, String dexPath, String librarySearchPath, File optimizedDirectory) { // save dexPath for BaseDexClassLoader this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions, definingContext); } private static Element[] makeDexElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions, ClassLoader loader) { } /* * TODO (dimitry): Revert after apps stops relying on the existence of this * method (see http://b/21957414 and http://b/26317852 for details) */ @SuppressWarnings("unused") private static Element[] makePathElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions) { return makeDexElements(files, optimizedDirectory, suppressedExceptions, null); } /** * Makes an array of directory/zip path elements for the native library search path, one per * element of the given array. */ private static NativeLibraryElement[] makePathElements(List<File> files) { } }
参考 : 8.0.0_r4/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
A n d r o i d 9.0 ( P i e A P I 28 ) \rm Android \ 9.0 \ ( Pie \ API \ 28 )Android 9.0 (Pie API 28) 系统中创建 Element[] dexElements 的方法 : /*package*/ final class DexPathList { private Element[] dexElements; public DexPathList(ClassLoader definingContext, String dexPath, String librarySearchPath, File optimizedDirectory) { // save dexPath for BaseDexClassLoader this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions, definingContext, isTrusted); } /** * Makes an array of dex/resource path elements, one per element of * the given array. */ private static Element[] makeDexElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions, ClassLoader loader) { return makeDexElements(files, optimizedDirectory, suppressedExceptions, loader, false); } private static Element[] makeDexElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) { } /* * TODO (dimitry): Revert after apps stops relying on the existence of this * method (see http://b/21957414 and http://b/26317852 for details) */ @SuppressWarnings("unused") private static Element[] makePathElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions) { return makeDexElements(files, optimizedDirectory, suppressedExceptions, null); } /** * Makes an array of directory/zip path elements for the native library search path, one per * element of the given array. */ private static NativeLibraryElement[] makePathElements(List<File> files) { } }
参考 : 9.0.0_r8/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
A n d r o i d 10.0 ( Q A P I 29 ) \rm Android \ 10.0 \ ( Q \ API \ 29 )Android 10.0 (Q API 29) 系统中创建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList { private Element[] dexElements; DexPathList(ClassLoader definingContext, String dexPath, String librarySearchPath, File optimizedDirectory, boolean isTrusted) { // save dexPath for BaseDexClassLoader this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions, definingContext, isTrusted); } /** * Makes an array of dex/resource path elements, one per element of * the given array. */ @UnsupportedAppUsage private static Element[] makeDexElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions, ClassLoader loader) { return makeDexElements(files, optimizedDirectory, suppressedExceptions, loader, false); } private static Element[] makeDexElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) { } /* * TODO (dimitry): Revert after apps stops relying on the existence of this * method (see http://b/21957414 and http://b/26317852 for details) */ @UnsupportedAppUsage @SuppressWarnings("unused") private static Element[] makePathElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions) { return makeDexElements(files, optimizedDirectory, suppressedExceptions, null); } /** * Makes an array of directory/zip path elements for the native library search path, one per * element of the given array. */ @UnsupportedAppUsage private static NativeLibraryElement[] makePathElements(List<File> files) { } }
参考 : 10.0.0_r6/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
二、不同 Android 系统创建 dex 数组源码对比
A n d r o i d 6.0 、 7.1 、 7.1 、 8.0 、 9.0 、 10 \rm Android \ 6.0 、 7.1、7.1、8.0、9.0、10Android 6.0、7.1、7.1、8.0、9.0、10 系统需要反射如下 makePathElements 方法 ;
@SuppressWarnings("unused") private static Element[] makePathElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions) { return makeDexElements(files, optimizedDirectory, suppressedExceptions, null); }
三、 Android 5.1 及以下系统反射方法并创建 Element[] dexElements
Android 5.1 及以下系统反射方法并创建 Element[] dexElements :
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1){ // 5.0, 5.1 makeDexElements // 反射 5.0, 5.1, 6.0 版本的 DexPathList 中的 makeDexElements 方法 makeDexElements = reflexMethod(pathList, "makeDexElements", ArrayList::class.java, File::class.java, ArrayList::class.java) var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>() addElements = makeDexElements.invoke(pathList, dexFiles, optimizedDirectory, suppressedExceptions) as Array<Any> }
四、 Android 6.0 及以下系统反射方法并创建 Element[] dexElements
Android 6.0 及以下系统反射方法并创建 Element[] dexElements :
}else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ // 7.0 以上版本 makePathElements // 反射 7.0 以上版本的 DexPathList 中的 makeDexElements 方法 makeDexElements = reflexMethod(pathList, "makePathElements", ArrayList::class.java, File::class.java, ArrayList::class.java) var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>() addElements = makeDexElements.invoke(pathList, dexFiles, optimizedDirectory, suppressedExceptions) as Array<Any> }
五、 完整代码示例
/* 2 . 在本应用中创建 Element[] dexElements 数组 , 用于存放解密后的 dex 文件 不同的 Android 版本中 , 创建 Element[] dexElements 数组的方法不同 , 这里需要做兼容 */ var makeDexElements: Method var addElements : Array<Any> if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1){ // 5.0, 5.1 makeDexElements // 反射 5.0, 5.1, 6.0 版本的 DexPathList 中的 makeDexElements 方法 makeDexElements = reflexMethod(pathList, "makeDexElements", ArrayList::class.java, File::class.java, ArrayList::class.java) var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>() addElements = makeDexElements.invoke(pathList, dexFiles, optimizedDirectory, suppressedExceptions) as Array<Any> }else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ // 7.0 以上版本 makePathElements // 反射 7.0 以上版本的 DexPathList 中的 makeDexElements 方法 makeDexElements = reflexMethod(pathList, "makePathElements", ArrayList::class.java, File::class.java, ArrayList::class.java) var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>() addElements = makeDexElements.invoke(pathList, dexFiles, optimizedDirectory, suppressedExceptions) as Array<Any> }