zoukankan      html  css  js  c++  java
  • 替换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();
           }
       }
    }
  • 相关阅读:
    Centos6.8下设置gitlab服务开机自启动,关闭防火墙开机自启动
    gitlab设置SSH key
    在centos6.8下安装gitlab遇到的坑
    recyclerView中的方法
    ListView中的方法
    tcp断开时分几步
    get,post区别
    cookie是什么,在什么地方会用到
    http和https的区别
    keystore是个嘛东西
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11639998.html
Copyright © 2011-2022 走看看