热修复原理

--摘自《Android进阶解密》

1.Instant Run编译部署

1)Hot swap:代码的增量改变不需要重启App,甚至不需要重启当前的Activity。修改一个现有方法中的代码时会采用Hot Swap

2)Warm Swap:App不需要重启,但是Activity需要重启。修改或删除一个现有的资源文件时会采用Warm Swap

3)Cold Swap:App需要重启,但是不需要重新安装。采用Cold Swap的情况很多,比如添加、删除或修改一个字段和方法、添加一个类等

2.Instant Run中的资源热修复可以简单地总结为两个步骤

 1)创建新的AssetManager,通过反射调用addAssetPath方法加载外部的资源,这样新创建的AssetManager就含有了外部资源

 2)将AssetManager类型的mAssets字段的引用全部替换为新创建的AssetManager

3.LoadNativeLibrary函数的流程图

  1)判断so是否被加载过,两次ClassLoader是否是同一个,避免so重复加载

  2)打开so并得到so句柄,如果so句柄获取失败,就返回false。创建新的SharedLibrary,如果传入path对应的library为空指针,就将新创建的SharedLibrary赋值给library,并将library存储到libraries_中

  3)查找JNI_OnLoad的函数指针,根据不同情况设置was_successful的值,最终返回该was_successful中

4.so修复主要有两个方案

  1)将so补丁插入到NativeLibraryElement数组的前部,让so补丁的路径先被返回和加载

  2)调用System的load方法来接管so的加载入口

5.代码修复主要有3种方案:底层替换方案、类加载方案和Instant Run方案

  1)类加载方案

    QQ空间的超级补丁和Nuwa是将补丁包放在Element数组的第一个元素得到优先加载

    微信Tinker将新旧APK做了diff,得到patch.dex,再将patch.dex与手机中APK的clsses.dex做合并,生成新的classes.dex,然后再运行时通过反射将classes.dex放在Element数组的第一个元素

    饿了么的Amigo则是将补丁包中每个dex对应的Element取出来,之后组成新的Element数组,在运行时通过反射用新的Element数组替换掉现有的Element数组

  2)底层替换方案

    AndFix采用的是替换ArtMethod结构体中的字段,这样会有兼容问题,因为厂商可能会修改ArtMethod结构体,导致方法替换失败

    Sophix采用的是替换整个ArtMethod结构体,这样不会存在兼容问题

欢迎关注我的微信公众号:安卓圈

posted @ 2019-01-07 18:33  嘉禾世兴  阅读(685)  评论(0编辑  收藏  举报