替換ClassLoader
package com.bluelesson.dummydex34;import android.app.Application;import android.content.Context;import android.content.res.AssetManager;import android.util.Log;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Field;import java.lang.reflect.Method;import dalvik.system.DexClassLoader;public class DummyApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // 1. 拷貝dex到安裝目錄下 String path = copyDex("src.dex"); // 2. 使用DexClassLoader,加載dex DexClassLoader dex = loadDex(path); // 3. 替換ClassLoader replaceClassLoader1(dex); } @Override public void onCreate() { super.onCreate(); } // 拷貝指定的文件從assets目錄中到/data/data/包名/files中 String copyDex(String dexName) { // 獲取assets目錄管理器 AssetManager as = getAssets(); // 合成路徑 // getFilesDir返回的就是/data/data/包名/files String path = getFilesDir() + File.separator + dexName; // File.separator 分隔符 Log.i("15pb-log", path); try { // 建立文件流 FileOutputStream out = new FileOutputStream(path); // 打開文件 InputStream is = as.open(dexName); // 循環讀取文件,拷貝到對應路徑 byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer)) != -1) { out.write(buffer, 0, len); } // 關閉文件 out.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); return ""; } return path; } // 得到指定文件的dex加載器 public DexClassLoader loadDex(String path) { // 建立dex文件的類加載器,返回DexClassLoader對象 DexClassLoader dex = new DexClassLoader( path, // dex路徑 getCacheDir().toString(), // 優化以後的文件的路徑 null, // 原生庫路徑 getClassLoader()); // 父類加載器 return dex; } public void replaceClassLoader1(DexClassLoader dexClassLoader){ try { // 1. 獲取ActivityThead類對象 // android.app.ActivityThread // 1.1 獲取類類型 Class clzActivityThead = Class.forName("android.app.ActivityThread"); // 1.2 獲取類方法 Method currentActivityThread = clzActivityThead.getMethod("currentActivityThread",new Class[]{}); // 1.3 調用方法 currentActivityThread.setAccessible(true); Object objActivityThread = currentActivityThread.invoke(null); // 2. 經過類對象獲取成員變量mBoundApplication //clzActivityThead.getDeclaredField() Field field = clzActivityThead.getDeclaredField("mBoundApplication"); // AppBindData field.setAccessible(true); Object data = field.get(objActivityThread); // 3. 獲取mBoundApplication對象中的成員變量info // 3.1 獲取 AppBindData 類類型 Class clzAppBindData = Class.forName("android.app.ActivityThread$AppBindData"); // 3.2 獲取成員變量info Field field1 = clzAppBindData.getDeclaredField("info"); // 3.3 獲取對應的值 //LoadedApk field1.setAccessible(true); Object info = field1.get(data); // 4. 獲取info對象中的mClassLoader // 4.1 獲取 LoadedApk 類型 Class clzLoadedApk = Class.forName("android.app.LoadedApk"); // 4.2 獲取成員變量 mClassLoader Field field2 = clzLoadedApk.getDeclaredField("mClassLoader"); field2.setAccessible(true); d2.set(info,dexClassLoader); } catch (Exception e) { e.printStackTrace(); } }}