简书链接:官方加载多个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();     } }