Android开发之热修复-Tinker-原理,这篇看完还不懂跟我去摆摊!(1)

总结

作为一名从事Android的开发者,很多人最近都在和我吐槽Android是不是快要凉了?而在我看来这正是市场成熟的表现,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!

资料.png
资料图.jpg

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

MultiDex.install(this);
}
}

2、分包配置

分包就创建了一个SecondActivity类做模拟异常和修复异常的入口,和一个Calculate模拟异常,做了10/0的操作,修复后为10/1

注:获取修复后的classes2.dex文件可以通过直接buildapk直接解压获取,或者用build-tools下的dx.bat执行命令获取

简单贴下SecondActivity,点击fix按钮后的代码:

private void update() {
//将下载的修复包,复制到私有目录,解压从.dex文件中取到对应的.class文件
//从sd卡取修复包
File sourceFile = new File(Environment.getExternalStorageDirectory(), Constants.DEX_NAME);
//目标文件
File targetFile = new File(getDir(Constants.DEX_DIR, Context.MODE_PRIVATE).getAbsolutePath() + File.separator + Constants.DEX_NAME);
if (targetFile.exists()) {
targetFile.delete();
Log.e(“update”,“删除原有dex文件(已使用的)”);
}
//将SD卡中的修复包copy到私有目录
FileUtils.copyFile(sourceFile,targetFile);
Log.e(“update”,“copy完成”);
FixDexUtils.loadDexFile(this);
}

3、FixModule

新建一个Module处理热修复的相关逻辑

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

只有五个文件,核心文件代码在FixDexUtils,其它是工具类,还有个定义了几个常量 看下FixDexUtils中的代码

public class FixDexUtils {

//修复文件可能有多个
private static HashSet loadedDex = new HashSet<>();

//不建议这么写,demo演示用
static {
loadedDex.clear();
}

public static void loadDexFile(Context context) {
//获取私有目录
File fileDir = context.getDir(Constants.DEX_DIR, Context.MODE_PRIVATE);
//遍历筛选私有目录中的.dex文件
File[] listFiles = fileDir.listFiles();

for (int i = 0; i < listFiles.length; i++) {
//文件名以.dex结尾,且不是主包.dex文件
if (listFiles[i].getName().endsWith(Constants.DEX_SUFFIX) && !“classes.dex”.equalsIgnoreCase(listFiles[i].getName())) {
loadedDex.add(listFiles[i]);
}
}
//创建自定义的类加载器
createDexClassLoader(context ,fileDir);
}

/**

  • @param context
  • @param fileDir
  • 创建自己的类加载器,加载私有目录的.dex文件,上面已经将修复包中的dex文件copy到私有目录
    */
    private static void createDexClassLoader(Context context, File fileDir) {
    //解压目录
    String optimizedDir = fileDir.getAbsolutePath()+File.separator+“opt_dex”;
    File fileOpt = new File(optimizedDir);
    if (!fileOpt.exists()) {
    fileOpt.mkdirs();
    }

for (File dex : loadedDex) {
//创建自己的类加载器,临时的
DexClassLoader classLoader = new DexClassLoader(dex.getAbsolutePath(), optimizedDir, null, context.getClassLoader());
//有一个修复文件,就插装一次
hotFix(classLoader,context);
}
}

private static void hotFix(DexClassLoader classLoader, Context context) {
try {
//获取系统的PathClassLoader类加载器
PathClassLoader pathClassLoader = (PathClassLoader)context.getClassLoader();
//获取自己的dexElements数组

Object myElements = ReflectUtils.getDexElements(ReflectUtils.getPathList(classLoader));
//获取系统的dexElements数组
Object systemElements = ReflectUtils.getDexElements(ReflectUtils.getPathList(pathClassLoader));
//合并数组,并排序,生成一个新的数组
Object dexElements=ArrayUtils.combineArray(myElements,systemElements);
//通过反射获取系统的pathList属性
Object systemPathList = ReflectUtils.getPathList(pathClassLoader);
//通过反射,将合并后新的dexElements赋值给系统的pathList
ReflectUtils.setFieldValue(systemPathList,“dexElements”,dexElements);
}catch (Exception e){
e.printStackTrace();
}
}
}

主要做的工作就是:就是上面那张流程图,就是先通过遍历,解压等操作,获取到需要执行热修复的.dex文件集合,遍历该集合,对应每次创建一个临时的DexClassLoader,然后执行修复步骤,细分就是六步:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最终实现效果如图(Demo使用手机是华为8.0的手机):

注:这里为了效果图更直观,已经重启过一次app
注: 这种方式实现的热修复必须要重启App才可以实现修复,这一点也是类加载机制决定的,如下图中修复之后再次打开加载执行修复后的classes.dex文件是在BaseApplication中调用了修复方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更多系列教程GitHub白嫖地址:https://github.com/Timdk857/Android-Architecture-knowledge-2-(白嫖可以,标星再走!)

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值