替換ClassLoader

替換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();       }   }}​
相關文章
相關標籤/搜索