替换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();
       }
   }
}
posted @ 2019-10-09 10:15  ltyandy  阅读(826)  评论(0编辑  收藏  举报