package loon.apk.shell; import android.content.Context; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import dalvik.system.DexClassLoader; public class APKDexLoader { private static final Map<String, DexClassLoader> apkLoader = new ConcurrentHashMap<String, DexClassLoader>(); public static DexClassLoader getClassLoader(String apkPath, Context cxt, ClassLoader parent) throws IOException { DexClassLoader pluginDexLoader = apkLoader.get(apkPath); if (pluginDexLoader == null) { final String dexOutputPath = cxt.getDir("shell", Context.MODE_PRIVATE).getAbsolutePath(); final String libOutputPath = cxt.getDir("shell_lib", Context.MODE_PRIVATE).getAbsolutePath(); APKTools.makedirs(dexOutputPath); APKTools.makedirs(libOutputPath); extractLibraries(apkPath, libOutputPath); pluginDexLoader = new DexClassLoader(apkPath, dexOutputPath, libOutputPath, parent); apkLoader.put(apkPath, pluginDexLoader); } return pluginDexLoader; } private static void extractLibraries(String dexPath, String libOutputPath) throws IOException { FileInputStream fis = new FileInputStream(new File(dexPath)); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); ZipEntry entry = null; while (null != (entry = zis.getNextEntry())) { if (entry.getName().startsWith("lib/") || (entry.getName().startsWith("libs/"))) { decompressZipFile(zis, entry, libOutputPath); } } } public static void decompressZipFile(ZipInputStream zipInputStream, ZipEntry entry, String destPath) throws IOException { String entryName = entry.getName(); String fileName = entryName.substring(entryName.lastIndexOf("/") + 1); File outFile = new File(destPath, fileName); if (!outFile.exists()) { outFile.createNewFile(); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(outFile)); int count = 0; byte buffer[] = new byte[2048]; while ((count = zipInputStream.read(buffer)) > 0) { bos.write(buffer, 0, count); } bos.flush(); bos.close(); } } }