Android热修复类加载机制

将修改好的类 编辑成dex

设置..\Sdk\build-tools\25.0.0次路径环境变量  并在cmd中输入dx进行验证

并将..\MyApplication\app\build\intermediates路径下的内容拷贝到任意路径  并在次路径打开命令行 输入下面命令

 dx --dex --output=class.jar com\mytext\*.class com\text\*.class

把打包好的jar 或 dex放到sdk指定路径 然后通过如下代码进行调用 即可完成修复 

FixDexUtil .fix(this, Environment.getExternalStorageDirectory() + File.separator + "class.dex");
import android.content.Context;
import android.widget.Toast;
import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import dalvik.system.DexClassLoader;
import dalvik.system.PathClassLoader;

public class FixDexUtil {
    public static void fix(Context context, String patchPath) {
        if (context == null) return;
        File fileDir = context.getDir("odex", Context.MODE_PRIVATE);
        //创建优化目录
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        doInject(context,patchPath,fileDir);
    }

    private static void doInject(Context appContext, String patchPath, File fileDir) {
        PathClassLoader pathClassLoader = (PathClassLoader) appContext.getClassLoader();
        DexClassLoader dexClassLoader = new DexClassLoader(patchPath, fileDir.getAbsolutePath(), null, pathClassLoader);
        try {
            Object dexPathList =  getField(dexClassLoader, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList");
            Object pathPathList = getField(pathClassLoader, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList");
            Object dexElements =  getField(dexPathList, dexPathList.getClass(), "dexElements");
            Object pathElements = getField(pathPathList, pathPathList.getClass(), "dexElements");
            Object resultElements = combineArray(dexElements, pathElements);
            Field field =  pathPathList.getClass().getDeclaredField("dexElements");
            field.setAccessible(true);
            field.set(pathPathList, resultElements);
            Toast.makeText(appContext, "修复完成", Toast.LENGTH_SHORT).show();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    private static Object combineArray(Object arrayLhs, Object arrayRhs) {
        Class<?> clazz = arrayLhs.getClass().getComponentType();
        int i = Array.getLength(arrayLhs);
        int j = Array.getLength(arrayRhs) + i;
        Object result = Array.newInstance(clazz, j);
        for (int k = 0; k < j; ++k) {
            if (k < i) {
                Array.set(result, k, Array.get(arrayLhs, k));
            } else {
                Array.set(result, k, Array.get(arrayRhs, k - i));
            }
        }
        return result;
    }

    private static Object getField(Object obj, Class<?> clazz, String fieldName) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            return field.get(obj);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

 

参考文章:

https://blog.csdn.net/u013928412/article/details/80428476

https://blog.csdn.net/u012911421/article/details/89705502

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值