2019-01-1221:47:21.5347359-7359/com.github.xch168.classloadertest I/TAG: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/base.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_dependencies_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_resources_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_0_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_1_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_2_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_3_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_4_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_5_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_6_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_7_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_8_apk.apk", zip file "/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.github.xch168.classloadertest-EmfX2txe3VMN2iMz4Iko-g==/lib/x86, /system/lib, /vendor/lib]]] 2019-01-1221:47:21.5347359-7359/com.github.xch168.classloadertest I/TAG: java.lang.BootClassLoader@5cf27a5
publicclassZygoteInit{ publicstaticvoidmain(String argv[]){ // ... if (startSystemServer) { Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the // child (system_server) process. if (r != null) { r.run(); return; } } } }
/** class definition context */ privatefinal ClassLoader definingContext;
/** * List of dex/resource (class path) elements. * Should be called pathElements, but the Facebook app uses reflection * to modify 'dexElements' (http://b/7726934). */ private Element[] dexElements;
/** List of native library path elements. */ // Some applications rely on this field being an array or we'd use a final list here /* package visible for testing */ NativeLibraryElement[] nativeLibraryPathElements;
/** List of application native library directories. */ privatefinal List<File> nativeLibraryDirectories;
/** List of system native library directories. */ privatefinal List<File> systemNativeLibraryDirectories; DexPathList(ClassLoader definingContext, String dexPath, String librarySearchPath, File optimizedDirectory, boolean isTrusted) { if (definingContext == null) { thrownew NullPointerException("definingContext == null"); }
if (dexPath == null) { thrownew NullPointerException("dexPath == null"); }
if (optimizedDirectory != null) { if (!optimizedDirectory.exists()) { thrownew IllegalArgumentException( "optimizedDirectory doesn't exist: " + optimizedDirectory); }
if (!(optimizedDirectory.canRead() && optimizedDirectory.canWrite())) { thrownew IllegalArgumentException( "optimizedDirectory not readable/writable: " + optimizedDirectory); } }
this.definingContext = definingContext;
ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>(); // save dexPath for BaseDexClassLoader this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions, definingContext, isTrusted);
// Native libraries may exist in both the system and // application library paths, and we use this search order: // // 1. This class loader's library path for application libraries (librarySearchPath): // 1.1. Native library directories // 1.2. Path to libraries in apk-files // 2. The VM's library path from the system property for system libraries // also known as java.library.path // // This order was reversed prior to Gingerbread; see http://b/2933456. this.nativeLibraryDirectories = splitPaths(librarySearchPath, false); this.systemNativeLibraryDirectories = splitPaths(System.getProperty("java.library.path"), true); List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories); allNativeLibraryDirectories.addAll(systemNativeLibraryDirectories);
privatestatic Element[] makeDexElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) { Element[] elements = new Element[files.size()]; int elementsPos = 0; /* * Open all files and load the (direct or contained) dex files up front. */ for (File file : files) { if (file.isDirectory()) { // We support directories for looking up resources. Looking up resources in // directories is useful for running libcore tests. elements[elementsPos++] = new Element(file); } elseif (file.isFile()) { String name = file.getName();
DexFile dex = null; if (name.endsWith(DEX_SUFFIX)) { // Raw dex file (not inside a zip/jar). try { dex = loadDexFile(file, optimizedDirectory, loader, elements); if (dex != null) { elements[elementsPos++] = new Element(dex, null); } } catch (IOException suppressed) { System.logE("Unable to load dex file: " + file, suppressed); suppressedExceptions.add(suppressed); } } else { try { dex = loadDexFile(file, optimizedDirectory, loader, elements); } catch (IOException suppressed) { /* * IOException might get thrown "legitimately" by the DexFile constructor if * the zip file turns out to be resource-only (that is, no classes.dex file * in it). * Let dex == null and hang on to the exception to add to the tea-leaves for * when findClass returns null. */ suppressedExceptions.add(suppressed); }
if (dex == null) { elements[elementsPos++] = new Element(file); } else { elements[elementsPos++] = new Element(dex, file); } } if (dex != null && isTrusted) { dex.setTrusted(); } } else { System.logW("ClassLoader referenced unknown path: " + file); } } if (elementsPos != elements.length) { elements = Arrays.copyOf(elements, elementsPos); } return elements; }
publicabstractclassClassLoader{ public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class<?> c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader }
if (c == null) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } return c; } }