栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android热修复学习(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android热修复学习(一)

前言 什么是热修复?

当我们应用上线后出现bug需要及时修复时,不用通过新发安装包,而是通过发布补丁包,在客户无感知的情况下修复bug;

热修复执行流程

开发侧修复bug提供补丁包给服务端,服务端将补丁包下发给客户端,客户端拿到补丁包后执行热修复相关代码进行修复;

常用三方热修复框架原理浅析 常见热修复方案比较

AndFix 阿里巴巴热修复方案【已停止维护】 github地址

AndFix

方案流程

在native动态替换java层的方法,通过native层hook java层的代码,从而改变执行顺序,进行修复;

Robust 美团热修复方案 github地址

Robust

方案流程

对每个函数都在编译打包阶段自动的插入一段代码,类似于代理,将方法执行的代码重定向到其他方法中;

   //编写的代码
    @Modify //改动代码后手动添加注解用于补丁包生成
    public long getIndex() {
        return 100;
    }

    //经过插桩后实际执行的代码
    public long getIndex() {
        if (changQuickRedirect != null) {
            return 修复的实现逻辑;
        }
        return 100;
    }
Tinker 腾讯热修复方案 github地址

Tinker
Tinker通过计算比对指定的Base Apk中的dex与修复后的Apk中的dex的区别,补丁包中的内容即为两者差分的描述。运行时将Base Apk中的dex与补丁包进行合成,重启后加载全新合成后的dex文件;

热修复简单实战

在前面我们学习了插件化相关知识,了解了类加载机制原理以及实现插件化调用,其实热修复和插件化实施差不多,区别主要是当进行dex合并的时候,需要将补丁包中的dex加载到base dex的前面,这样才能达到加载补丁包中class的目的。关于类加载机制原理这里就不再赘述,有需要可直接参考:Android插件化学习之初识类加载机制

这里我们简单写个热修复相关的demo;

  • 先写个bug~~
public class TestUtils {
   public static void test() {
       throw new IllegalArgumentException("故意写bug....");
       // Log.e(TestUtils.class.getSimpleName(), "bug 已修复...");
   }
}
  • 将bug修复并打包成dex文件存放到sdcard下
public class TestUtils {
   public static void test() {
      // throw new IllegalArgumentException("故意写bug....");
        Log.e(TestUtils.class.getSimpleName(), "bug 已修复...");
   }
}

使用dx命令打包成dex存放在sdcard目录下;

  • 将修复后的dex与当前dex合并
public class LoadUtils {

   public static void loadPluginDexFile(Context context) {
       try {
           Class baseDexClassLoaderClazz = Class.forName("dalvik.system.BaseDexClassLoader");
           Field pathListField = baseDexClassLoaderClazz.getDeclaredField("pathList");
           pathListField.setAccessible(true);

           Class dexPathListClazz = Class.forName("dalvik.system.DexPathList");
           Field dexElementsField = dexPathListClazz.getDeclaredField("dexElements");
           dexElementsField.setAccessible(true);

           //获取宿主dexElements
           ClassLoader hostClassLoader = context.getClassLoader();
           Object pathList = pathListField.get(hostClassLoader);
           Object[] hostDexElements = (Object[]) dexElementsField.get(pathList);

           //获取插件dexElements
           DexClassLoader pluginDexClassLoader = new DexClassLoader("/sdcard/patch.dex", context.getCacheDir().getAbsolutePath(), null, hostClassLoader);
           Object pluginPathList = pathListField.get(pluginDexClassLoader);
           Object[] pluginDexElements = (Object[]) dexElementsField.get(pluginPathList);

           //合并两个dex Element数组【修复插件的dex放在数组前面】
           Object[] resultDexElements = (Object[]) Array.newInstance(hostDexElements.getClass().getComponentType(), hostDexElements.length + pluginDexElements.length);
           System.arraycopy(pluginDexElements, 0, resultDexElements, 0, pluginDexElements.length);
           System.arraycopy(hostDexElements, 0, resultDexElements, pluginDexElements.length, hostDexElements.length);
           //将合并的结果复制给宿主dex Elements
           dexElementsField.set(pathList, resultDexElements);
       } catch (Exception e) {
           e.printStackTrace();
           Log.e("LoadUtils", e.toString());
       }
   }

Android N混合编译

ART是在Android KitKat(Android4.0)进入并在Lolipop(Android 5.0)中设为默认运行环境,可以看作Dalvik 2.0;
ART模式在Android7.0之前安装APK会采用AOT(Ahead of Time:提前编译、静态编译)预编译为机器码;
而在Android N(Android7.0)使用混合模式的运行时,应用在安装时不做编译,而是运行时解释字节码,同时在JIT编译了一些代码后将这些代码信息记录至Profile文件,等到设备空闲的时候使用AOT(All-Of-the-Time compilation:全时段编译)编译生成称为app_image的base.art(类对象映像)文件,这个art文件会在apk启动时自动加载(相当于缓存)。根据类加载原理,类被加载后无法替换,因此存在无法修复的问题;

混合编译热修复解决方案

运行时,通过反射替换系统创建的PathClassLoader
App image中的class是插入到PathClassLoader中的ClassTable中;假设我们完全废弃掉PathClassLoader,而是采用新建一个PathClassLoader加载后续所有的类,即可达到将缓存数据无用化的目的;具体方式可参考Tinker中的替换方式;

总结

热修复实现原理归根还是类加载机制,与插件化方案的不同之处在于修复dex需要放在合并后的dex数组前面,才能执行修复后的代码;本质上都是对于类加载机制的运用;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1036803.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号