简书链接:官方加载多个dex的核心代码 文章字数:40,阅读全文大约需要1分钟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 private static List<MultiDexExtractor.ExtractedDex> performExtractions(File sourceApk, File dexDir) throws IOException { String extractedFilePrefix = sourceApk.getName() + ".classes"; prepareDexDir(dexDir, extractedFilePrefix); List<MultiDexExtractor.ExtractedDex> files = new ArrayList(); ZipFile apk = new ZipFile(sourceApk); try { int secondaryNumber = 2; for(ZipEntry dexFile = apk.getEntry("classes" + secondaryNumber + ".dex"); dexFile != null; dexFile = apk.getEntry("classes" + secondaryNumber + ".dex")) { String fileName = extractedFilePrefix + secondaryNumber + ".zip"; MultiDexExtractor.ExtractedDex extractedFile = new MultiDexExtractor.ExtractedDex(dexDir, fileName); files.add(extractedFile); Log.i("MultiDex", "Extraction is needed for file " + extractedFile); int numAttempts = 0; boolean isExtractionSuccessful = false; while(numAttempts < 3 && !isExtractionSuccessful) { ++numAttempts; extract(apk, dexFile, extractedFile, extractedFilePrefix); try { extractedFile.crc = getZipCrc(extractedFile); isExtractionSuccessful = true; } catch (IOException var19) { isExtractionSuccessful = false; Log.w("MultiDex", "Failed to read crc from " + extractedFile.getAbsolutePath(), var19); } Log.i("MultiDex", "Extraction " + (isExtractionSuccessful ? "succeeded" : "failed") + " - length " + extractedFile.getAbsolutePath() + ": " + extractedFile.length() + " - crc: " + extractedFile.crc); if (!isExtractionSuccessful) { extractedFile.delete(); if (extractedFile.exists()) { Log.w("MultiDex", "Failed to delete corrupted secondary dex '" + extractedFile.getPath() + "'"); } } } if (!isExtractionSuccessful) { throw new IOException("Could not create zip file " + extractedFile.getAbsolutePath() + " for secondary dex (" + secondaryNumber + ")"); } ++secondaryNumber; } } finally { try { apk.close(); } catch (IOException var18) { Log.w("MultiDex", "Failed to close resource", var18); } } return files; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 private static void extract(ZipFile apk, ZipEntry dexFile, File extractTo, String extractedFilePrefix) throws IOException, FileNotFoundException { InputStream in = apk.getInputStream(dexFile); ZipOutputStream out = null; File tmp = File.createTempFile("tmp-" + extractedFilePrefix, ".zip", extractTo.getParentFile()); Log.i("MultiDex", "Extracting " + tmp.getPath()); try { out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tmp))); try { ZipEntry classesDex = new ZipEntry("classes.dex"); classesDex.setTime(dexFile.getTime()); out.putNextEntry(classesDex); byte[] buffer = new byte[16384]; for(int length = in.read(buffer); length != -1; length = in.read(buffer)) { out.write(buffer, 0, length); } out.closeEntry(); } finally { out.close(); } if (!tmp.setReadOnly()) { throw new IOException("Failed to mark readonly \"" + tmp.getAbsolutePath() + "\" (tmp of \"" + extractTo.getAbsolutePath() + "\")"); } Log.i("MultiDex", "Renaming to " + extractTo.getPath()); if (!tmp.renameTo(extractTo)) { throw new IOException("Failed to rename \"" + tmp.getAbsolutePath() + "\" to \"" + extractTo.getAbsolutePath() + "\""); } } finally { closeQuietly(in); tmp.delete(); } }