package org.bbs.apklauncher; import java.io.IOException; import java.util.ArrayList; import java.util.List; import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.os.Build; import android.util.Log; import dalvik.system.DexClassLoader; import dalvik.system.DexFile; public class TargetClassLoader extends ClassLoader //DexClassLoader { private static final String TAG = TargetClassLoader.class.getSimpleName(); private static /*final*/ boolean DEBUG = true; private DexFile mHostDexFile; private DexFile mTargetDexFile; private int mLevel; public TargetClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent, String targetPackageName, Context hostContext) { // super(dexPath, optimizedDirectory, libraryPath, parent); super(parent); try { String hostApkPath = hostContext.getApplicationInfo().publicSourceDir; String hostPName = hostContext.getPackageName(); mHostDexFile = DexFile.loadDex(hostApkPath, optimizedDirectory + "/" + hostPName + ".dex", 0); mTargetDexFile = DexFile.loadDex(dexPath, optimizedDirectory + "/" + targetPackageName + ".dex", 0); } catch (IOException e) { e.printStackTrace(); } } @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) @Override protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { if (DEBUG) { mLevel++; Log.d(TAG, makePrefix(mLevel) + className); } Class<?> c = null; if (shouldLoad(className)){ c = mHostDexFile.loadClass(className, this); if (c != null) { // Log.d(TAG, "/\\ /\\ /\\" + className + " ==> " + c.getClassLoader()); } } if (c == null ) { c = mTargetDexFile.loadClass(className, this); if (c != null) { // Log.d(TAG, "/\\/\\/\\" + className + " ==> " + c.getClassLoader()); } } if (c == null) { c = super.loadClass(className, resolve); } if (resolve){ resolveClass(c); } if (DEBUG) { if (c != null) { Log.d(TAG, makePrefix(mLevel) + className + " ==> " + c.getClassLoader()); mLevel--; } } return c; } String makePrefix(int level){ String str = ""; for (int i = 1; i < level; i++){ str += " "; } return str; // return (level == 1 ? "\n" : "") + level; } protected boolean shouldLoad(String className) { return sList.contains(className) // || className.matches("android\\.support.*") || className.startsWith("org.bbs.apklauncher") ; } static List<String> sList = new ArrayList<String>(); static { sList.add("android.app.Activity"); sList.add("android.app.ListActivity"); sList.add("android.support.v4.app.FragmentActivity"); } }