privatestatic Element[] makeDexElements(List<File> files, File optimizedDirectory, List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) { Element[] elements = newElement[files.size()]; intelementsPos=0; /* * Open all files and load the (direct or contained) dex files up front. */ for (File file : files) { if (file.isDirectory()) { // element path 为 文件夹 // ...... } elseif (file.isFile()) { Stringname= file.getName();
DexFiledex=null; if (name.endsWith(DEX_SUFFIX)) { // end with .dex // ..... } else { // 加载dex并保存在数组中 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); }
// 创建系统的classloader,pair的低一个参数是标准的共享库 // 第二个参数是app dex加载完之后需要加载的库 // the first is for standard shared libraries // and the second is list for shared libraries that code should be loaded after the dex Pair<List<ClassLoader>, List<ClassLoader>> sharedLibraries = createSharedLibrariesLoaders(mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath, libraryPermittedPath);
// if configured to do so, shared libs are split into 2 collections: those that are // on the class path before the applications code, which is standard, and those // specified to be loaded after the applications code. HashSet<String> libsToLoadAfter = newHashSet<>(); ResourcessystemR= Resources.getSystem(); Collections.addAll(libsToLoadAfter, systemR.getStringArray( R.array.config_sharedLibrariesLoadedAfterApp));
// 需要在app apk加载之前加载的库集合 // 通常是5个 // 1. /system/framework/android.test.base.jar // 2. /system/framework/android.test.mock.jar // 3. /system/framework/org.apache.http.legacy.jar // 4. /system/framework/android.test.runner.jar // 5. libOpenCL-pixel.so List<ClassLoader> loaders = newArrayList<>(); // 需要在app apk加载之后加载的库集合。通常是空的。 List<ClassLoader> after = newArrayList<>(); for (SharedLibraryInfo info : sharedLibraries) { if (info.isNative()) { // Native shared lib doesn't contribute to the native lib search path. Its name is // sent to libnativeloader and then the native shared lib is exported from the // default linker namespace. continue; } if (info.isSdk()) { // SDKs are not loaded automatically. continue; } if (libsToLoadAfter.contains(info.getName())) { if (DEBUG) { Slog.v(ActivityThread.TAG, info.getName() + " will be loaded after application code"); } after.add(createSharedLibraryLoader( info, isBundledApp, librarySearchPath, libraryPermittedPath)); } else { loaders.add(createSharedLibraryLoader( info, isBundledApp, librarySearchPath, libraryPermittedPath)); } } returnnewPair<>(loaders, after); }
ClassLoader getClassLoaderWithSharedLibraries( String zip, int targetSdkVersion, boolean isBundled, String librarySearchPath, String libraryPermittedPath, ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries, List<ClassLoader> sharedLibrariesLoadedAfterApp) { // For normal usage the cache key used is the same as the zip path. return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath, libraryPermittedPath, parent, zip, classLoaderName, sharedLibraries, nativeSharedLibraries, sharedLibrariesLoadedAfterApp); }