热修复 -- Sophix & Tinker

一、Sophix & Tinker

Sophix & Tinker

二、使用

Sophix使用

Tinker使用

三、原理

代码修复

代码修复有两大主要方案,一种是阿里系的底层替换方案,另一种是腾讯系的类加载方案。这两类方案各有优缺点:

  • 底层替换方案限制颇多,但时效性最好,加载轻快,立即见效。
  • 类加载方案时效性差,需要重新冷启动才能见效,但修复范围广,限制少。

底层替换方案(热替换代码修复:Sophix):
底层替换方案是在已经加载的类中通过动态修改native指针来直接替换原有方法,是在原有类的基础上进行修改的,因而无法实现对原有类进行方法和字段的增减,因为这样将破坏原有类的结构。

底层替换方案

类加载方案(冷启动代码修复:Tinker Sophix):
类加载方案的原理是在App重新启动后让ClassLoader去加载新的类。因为在App启动到一半的时候,所有需要发生变更的类已经被加载过了,在Android系统上是无法对一个类进行卸载的。如果不重启,原有的类还在虚拟机中,就无法加载新类。因此,只有在下次重启的时候,在还没有运行到业务逻辑之前抢先加载补丁中的新类,这样后续访问这个类时,就会被解析为新类,从而达到热修复的目的。

  • Tinker
    原理:通过差量的方式得到patch.dex,然后将patch.dex与应用的旧dex文件合并成一个新dex文件,合成的全量dex文件插入到dexElements的第一个位置,dexElements里面的每个Element实际上就是dex文件,classLoader在启动时,会按顺序加载dex文件,使修复类所在的全量dex包被优先加载,从而完成替换。
    优点:自研dex差异算法,补丁包很小。
    缺点:dex合并内存消耗在vm heap上,容易OOM,最后导致dex合并失败。


    Tinker类加载方案
  • Sophix
    Art虚拟机:默认支持多dex加载,虚拟机会优先加载命名为classes.dex的文件。Sophix将补丁文件命名为classes.dex,并对原有dex文件进行排序,这样Art虚拟机就会先加载补丁文件,后续加载的同类名的类会被忽略。


    Sophix类加载方案-Art虚拟机

    Dalvik虚拟机:默认只加载classes.dex,其他dex则被忽略,Sophix需要一个全量dex。Tinker是采用自研的dex差异算法,从方法和指令的维度进行dex合成,但dex合成过程发生在虚拟机堆内存上,修复的成功率受性能影响。而Sophix换了一种思路,从类的维度对照补丁包中出现的类,在原有包中做删除操作。


    Sophix类加载方案-Dalvik虚拟机

资源修复

Instant Run:
目前市面上的很多资源修复方案基本上都是参考了Instant Run的实现。Instant Run中的资源热修复分为两步:
1.构造一个新的AssetManager,并通过反射调用addAssetPath函数,然后把完整的新资源包加载到AssetManager中。这样就得到了一个含有所有新资源的AssetManager。
2.找到所有之前引用到原有AssetManager的地方,通过反射,把引用出替换为新的AssetManager。

Sophix:
没有直接参考Instant Run的技术,构造了一个package id为0x66的资源包,这个包里只包含需要改变的资源项(原有包里面没有的新增资源,以及原有内容发生了改变的资源),然后直接在原有AssetManager中通过addAssetPath函数添加这个包就可以了。由于补丁包的package id为0x66,不与目前已经加载的地址为0x7f的包冲突,因此直接加载到已有的AssetManager中就可以直接使用了。整个资源替换的方案优势如下:

  • 不修改AssetManager的引用处,替换资源更快更完全。
  • 不必下发完整包,补丁包中只包含变动的资源。
  • 不需要在运行时合成完整包,不占用运行时计算和内存资源。

唯一有个需要注意的地方就是,因为对新的资源的引用是在新代码中,所有资源修复是需要代码修复的支持的。也因此所有资源修复方案必然是附带代码修复的。

so库修复

Java API提供以下两个接口加载一个so库:

  • System.loadLibrary(String libName):传进去的参数是so库名称,表示的so库文件,位于APK压缩文件中的libs目录,最后复制到APK安装目录下。
  • System.load(String pathName):传进去的参数是so库在磁盘中的完整路径,加载一个自定义外部so库文件。

so库的修复本质上是对native方法的修复和替换。

Sophix:
采用的是类似类修复反射注入方式。把补丁so库的路径插入到nativeLibraryDirectories数组的最前面,就能够达到加载so库的时候是补丁so库的目录从而修复Bug的目的。采用这种方案,完全由Sophix在启动期间反射注入补丁中的so库,重启生效。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容