Java tutorial
//package com.java2s; //License from project: Apache License import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Build; import dalvik.system.DexFile; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; public class Main { private static final String EXTRACTED_NAME_EXT = ".classes"; private static final String EXTRACTED_SUFFIX = ".zip"; private static final String SECONDARY_FOLDER_NAME = "code_cache" + File.separator + "secondary-dexes"; private static final String PREFS_FILE = "multidex.version"; private static final String KEY_DEX_NUMBER = "dex.number"; /** * get all the classes name in "classes.dex", "classes2.dex", .... * * @param context the application context * @return all the classes name * @throws PackageManager.NameNotFoundException * @throws IOException */ public static List<String> getAllClasses(Context context) throws PackageManager.NameNotFoundException, IOException { List<String> classNames = new ArrayList<String>(); for (String path : getSourcePaths(context)) { try { DexFile dexfile = null; if (path.endsWith(EXTRACTED_SUFFIX)) { //NOT use new DexFile(path), because it will throw "permission error in /data/dalvik-cache" dexfile = DexFile.loadDex(path, path + ".tmp", 0); } else { dexfile = new DexFile(path); } Enumeration<String> dexEntries = dexfile.entries(); while (dexEntries.hasMoreElements()) { classNames.add(dexEntries.nextElement()); } } catch (IOException e) { throw new IOException("Error at loading dex file '" + path + "'"); } } return classNames; } /** * get all the dex path * * @param context the application context * @return all the dex path * @throws PackageManager.NameNotFoundException * @throws IOException */ public static List<String> getSourcePaths(Context context) throws PackageManager.NameNotFoundException, IOException { ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0); File sourceApk = new File(applicationInfo.sourceDir); File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME); List<String> sourcePaths = new ArrayList<String>(); sourcePaths.add(applicationInfo.sourceDir); //add the default apk path //the prefix of extracted file, ie: test.classes String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT; //the total dex numbers int totalDexNumber = getMultiDexPreferences(context).getInt(KEY_DEX_NUMBER, 1); for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) { //for each dex file, ie: test.classes2.zip, test.classes3.zip... String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX; File extractedFile = new File(dexDir, fileName); if (extractedFile.isFile()) { sourcePaths.add(extractedFile.getAbsolutePath()); //we ignore the verify zip part } else { throw new IOException("Missing extracted secondary dex file '" + extractedFile.getPath() + "'"); } } return sourcePaths; } private static SharedPreferences getMultiDexPreferences(Context context) { return context.getSharedPreferences(PREFS_FILE, Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ? Context.MODE_PRIVATE : Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS); } }