What is HotFix?

以补丁的方式动态修复紧急Bug,不再需要重新发布App,不再需要用户重新下载,覆盖安装(来自:安卓App热补丁动态修复技术介绍)
HotFix原理
首先HotFix原理是基于Android Dex分包方案的,而Dex分包方案的关键就是Android的ClassLoader体系。ClassLoader的继承关系如下:

ClassLoader继承关系

这里我们可以用的是PathClassLoader和DexClassLoader,接下来看看这两个类的注释:

PatchClassLoader
/**
* Provides a simple {@link ClassLoader} implementation that operates on a list
* of files and directories in the local file system, but does not attempt to
* load classes from the network. Android uses this class for its system class
* loader and for its application class loader(s).
*/

这个类被用作系统类加载器和应用类(已安装的应用)加载器。

DexClassLoader
/**
* A class loader that loads classes from {@code .jar} and {@code .apk} files
* containing a {@code classes.dex} entry. This can be used to execute code not
* installed as part of an application.
*/

注释可以看出,这个类是可以用来从.jar文件和.apk文件中加载classed.dex,可以用来执行没有安装的程序代码。
通过上面的两个注释可以清楚这两个类的作用了,很显然我们要用的是DexClassLoader,对插件化了解的小伙伴们对这个类肯定不会陌生的,对插件化不了解的也没关系。下面会更详细的介绍。
我们知道了PathClassLoader和DexClassLoader的应用场景,接下来看一下是如何加载类的,看上面的继承关系这里两个类都是继承自BaseDexClassLoader,所以查找类的方法也在BaseDexClassLoader中,下面是部分源码:

/*** Base class for common functionality between various dex-based* {@link ClassLoader} implementations.*/
public class BaseDexClassLoader extends ClassLoader {/** structured lists of path elements */private final DexPathList pathList;//...some code@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {Class clazz = pathList.findClass(name);if (clazz == null) {throw new ClassNotFoundException(name);}return clazz;}//...some code
}

可以看到在findClass()方法中用到了pathList.findClass(name),而pathList的类型是DexPathList,下面看一下DexPathList的findClass()方法源码:

/*** A pair of lists of entries, associated with a {@code ClassLoader}.* One of the lists is a dex/resource path — typically referred* to as a "class path" — list, and the other names directories* containing native code libraries. Class path entries may be any of:* a {@code .jar} or {@code .zip} file containing an optional* top-level {@code classes.dex} file as well as arbitrary resources,* or a plain {@code .dex} file (with no possibility of associated* resources).** <p>This class also contains methods to use these lists to look up* classes and resources.</p>*/
/*package*/ final class DexPathList {/** list of dex/resource (class path) elements */private final Element[] dexElements;/*** Finds the named class in one of the dex files pointed at by* this instance. This will find the one in the earliest listed* path element. If the class is found but has not yet been* defined, then this method will define it in the defining* context that this instance was constructed with.** @return the named class or {@code null} if the class is not* found in any of the dex files*/public Class findClass(String name) {for (Element element : dexElements) {DexFile dex = element.dexFile;if (dex != null) {Class clazz = dex.loadClassBinaryName(name, definingContext);if (clazz != null) {
                     return clazz;}}}
return null;}
}

这个方法里面有调用了dex.loadClassBinaryName(name, definingContext),然后我们来看一下DexFile的这个方法:

/*** Manipulates DEX files. The class is similar in principle to* {@link java.util.zip.ZipFile}. It is used primarily by class loaders.* <p>* Note we don't directly open and read the DEX file here. They're memory-mapped* read-only by the VM.*/
public final class DexFile {/*** See {@link #loadClass(String, ClassLoader)}.** This takes a "binary" class name to better match ClassLoader semantics.** @hide*/public Class loadClassBinaryName(String name, ClassLoader loader){return defineClass(name, loader, mCookie);}private native static Class defineClass(String name, ClassLoader loader, int cookie);
}

好了,关联的代码全部贴上了,理解起来并不难,总结一下流程:BaseDexClassLoader中有一个DexPathList对象pathList,pathList中有个Element数组dexElements(Element是DexPathList的静态内部类,在Element中会保存DexFile的对象),然后遍历Element数组,通过DexFile对象去查找类。
更通俗的说:

一个ClassLoader可以包含多个dex文件,每个dex文件是一个Element,多个dex文件排列成一个有序的数组dexElements,当找类的时候,会按顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找类则返回,如果找不到从下一个dex文件继续查找。(出自安卓App热补丁动态修复技术介绍)
so,通过上面介绍,我们可以将patch.jar(补丁包),放在dexElements数组的第一个元素,这样优先找到我们patch.jar中的新类去替换之前存在bug的类。
方案有了,但是我们还差一个步骤,就是防止类被打上CLASS_ISPREVERIFIED的标记
解释一下:在apk安装的时候,虚拟机会将dex优化成odex后才拿去执行。在这个过程中会对所有class一个校验。校验方式:假设A该类在它的static方法,private方法,构造函数,override方法中直接引用到B类。如果A类和B类在同一个dex中,那么A类就会被打上CLASS_ISPREVERIFIED标记。A类如果还引用了一个C类,而C类在其他dex中,那么A类并不会被打上标记。换句话说,只要在static方法,构造方法,private方法,override方法中直接引用了其他dex中的类,那么这个类就不会被打上CLASS_ISPREVERIFIED标记。(引用自Android热补丁动态修复技术(二):实战!CLASS_ISPREVERIFIED问题!)
O..O..OK,现在很清楚了,实现热修复,我们需要完成两个任务:
改变BaseDexClassLoader中的dexElements数组,将我们的patch.jar插入到dexElements数组的第一个位置。
在打包的时候,我们要阻止类被打上CLASS_ISPREVERIFIED标记

HotFix框架汇总
RocooFix(推荐)
Nuwa
HotFix
AndFix
Tinker_imitator(微信热更新方案实践)

RoccoFix使用问题
RocooFix的正确教程,不生成patch.jar请按这个步骤来执行
待更新

参考
安卓App热补丁动态修复技术介绍
Android dex分包方案
Android 热补丁动态修复框架小结
Android热补丁动态修复技术(一):从Dex分包原理到热补丁
Android热补丁动态修复技术(二):实战!CLASS_ISPREVERIFIED问题!
Android热补丁动态修复技术(三)—— 使用Javassist注入字节码,完成热补丁框架雏形(可使用)
Android热补丁动态修复技术(四):自动化生成补丁——解决混淆问题

文/zyyoona7(简书作者)
原文链接:http://www.jianshu.com/p/6f0ae1e364d9
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Android HotFix相关推荐

  1. Android Hotfix 新方案——Amigo 源码解读

    现在 hotfix 框架有很多,原理大同小异,基本上是基于qq空间这篇文章 或者微信的方案.可惜的是微信的 Tinker 以及 QZone 都没有将其具体实现开源出来,只是在文章中分析了现有各个 ho ...

  2. android hotfix nuwa2, support gradle 2.x

    说明: 热修复是什么?热修复就是app出现bug之后无需用户更新app就能静默修复bug,注意不是web页面而是可以静默修复原生bug哦. 外面的热修复框架都是公说公有理,婆说婆有理,既然如此,我就都 ...

  3. Android AndFix热补丁动态修复框架使用教程

    简介 已经上线的项目发现BUG,紧急修复BUG发布新版本?No,也许你需要AndFix. AndFix 是阿里巴巴开源的 Android 应用热修复工具,帮助 Anroid 开发者修复应用的线上问题. ...

  4. Android热更新实现方式

    一.Tinker tinkerpatch.com/ github.com/Tencent/tin- github.com/Tencent/tin- 别人写的微信tinker补丁管理,后端代码+客户端s ...

  5. 阿里热更新android,阿里最新热更新使用采坑记录

    1.必须在AndroidManifest.xml中配置 android:name="com.taobao.android.hotfix.IDSECRET" android:valu ...

  6. HotFix移动热修复详解

    集成步骤: 1.打开阿里云选择产品------移动热修复: 2.登录: 3.点击控制台: 4.产品与服务点击移动热修复: 5.创建App 7.返回控制台管理页面已经有创建的应用--------点击管理 ...

  7. 2017常见android面试题

    介绍自己负责的部分,如何实现的. 框架的搭建 排查问题以及结解决方式 兼容性保证 性能优化 上线之后模块导致crash的比例 自定义view viewGroup 这个就是约定的几个方法,onMeasu ...

  8. Android热更新技术的研究与实现Sophix

    所以阿里爸爸一直在进步着呢,知道技术存在问题就要去解决问题,这不,从Dexposed-->AndFix-->HotFix-->Sophix,技术是越来越成熟了. Android热更新 ...

  9. Android中高级进阶知识(最新动脑学院安卓进阶视频 )

    Android中高级进阶知识点整理 转载 https://blog.csdn.net/lou_liang/article/details/8285653 那么接下来的文章就是高级进阶,其中或者引用或者 ...

  10. android 热修复 框架,十分钟教会你使用安卓热修复框架AndFix

    腾讯最近开发出一个Tinker,阿里也有一个Dexposed框架,当然还有一个就是今天的主角热修复框架AndFix.接下来,我会从它的概念.原理.使用方法等为你详细介绍. 1.什么是AndFix? A ...

最新文章

  1. deepstream-开放式实时服务器
  2. Windows 2008 部署服务之Windows 7 应答文件创建
  3. android 音视频流采集,Android 音视频开发(四):使用 Camera API 采集视频数据(示例代码)...
  4. 数学--数论--鸽巢原理
  5. Dapr 已在塔架就位 将发射新一代微服务
  6. 2019 ICPC Asia Yinchuan Regional(9 / 13)
  7. hdu 6153 A Secret kmp + dp
  8. 关于用VS写C程序运行时出现烫字以及乱码的问题的原因
  9. React Native开发指南-在原生和React Native间通信
  10. 一个 WordPress 安装,多个博客
  11. db2取数据库日期时间_DB2数据库取得当前时间的正确解析
  12. 【BZOJ 1202】 [HNOI2005]狡猾的商人
  13. 在MAC OS X下安装usb转串口驱动(PL2303主控芯片)
  14. android开机优化-framework
  15. 谈谈亲历的WMS、MES与ERP的集成之路
  16. Verilog-移位操作(算术右移与逻辑右移)
  17. Java将汉字转为拼音
  18. Tetris项目总结
  19. 工业螺旋齿轮行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  20. 青龙面板之KS普通版、极速版【详细教程】

热门文章

  1. MISC总结——隐写术(一)
  2. java 微博发布时间_java 对新浪微博微博的发表时间解析
  3. ping命令显示的TTL是什么意思
  4. 渐进式Express源码学习6-独孤求败
  5. gis 六边形网格_ArcGIS中的奇技淫巧(Ⅱ)—蜂巢网格图
  6. Module not found: Error: Can‘t resolve ‘core-js/fn/promise‘
  7. 双创项目_宫颈癌风险智能检测(2)
  8. Asp .NetCore 支付宝网页授权登录
  9. web开发框架技术有哪些?
  10. 梦殇 chapter one