简单了解Robust(一)

因为工作需要,所以需要在公司项目中增加Robust补丁,其实操作流程很简单,只是对其中原理不是很理解,下面简单看一下生成的文件:

一、首先看一下添加Robust依赖之后生成的apk文件的代码:

线上apk经过Robust的代码

经过查看可以了解到,Robust给每一个类(另一个MainActivity类也增加了)增加了一个叫做ChangeQuickRedirect的静态变量,然后在每一个方法的最前面增加了一段代码,目前我们还不知道这段代码的含义,但是大概知道,如果能够PatchProxy.isSuuport()为true的话,那么就不走原来的逻辑,而是直接走插桩代码的逻辑。

下面简单看一下PatchProxy.isSupport里面有什么:

PatchProxy.isSupport()
PatchProxy.accessDispatch()

经过上面代码,其实主要有两个疑问:

- 如何将那一段插桩代码插入进去?

- 每个类中都会插入一个ChangeQuickRedirect静态变量,在走到具体方法时,会在isSupport里面判断该变量是否为空,那么是什么时候对这个ChangeQuickRedirect变量赋值的呢?

二、下面看一下补丁patch.jar(patch.dex)代码:

打开之后一共有三个类:

1、PatchesInfoImpl类:

可以看到里面逻辑很简单,是将待修复的方法所在类与另一个XXXXPatchControl类放进了集合:

PatchesInfoImpl类

2、下面看一下SecondActivityPatchControl类:

首先可以看到这个类实现了ChangeQuickRedirect接口,并重写了isSupport和accessDispatch方法:

补丁类

重写了isSupport方法:(内部逻辑没太看懂,但是应该只是判断一下当前方法是不是要fix的那个方法,需要去撸源码看一下)

重写isSupport方法

重写了accessDispatch方法,因为是反编译代码,所以其实没太看懂,但是起码可以看到重新new了SecondActivityPatch对象,并且执行了其中的fix方法,所以应该来说最终真正的补丁后的方法在SecondActivityPatch中:

重写accessDispatch方法

3、下面看一下最后一个类:SecondActivityPatch

fix之后的逻辑

看完了上面补丁里面的代码,其实还是有一个最开始的疑问,这个patch补丁是如何加载以及生效的?因为代码被混淆,我们只好去看一下Robust的wiki:

wiki说明是因为如何加载需要开发者自定义,因此官方给出了一个demo,在demo中可以看到,逻辑比较简单,主要有两步:

(1)、联网下载补丁;

(2)、使用DexClassLoader加载patch补丁,加载时,首先反射获取com.meituan.robust.patch.PatchesInfoImpl的对应的Class对象,通过调用其中的getPatchedClassesInfo()方法来查看哪些类有修改,获取patchClass以及oldClass,同时使用反射修改oldClass中对应的变量值ChangeQuickRedirect,改成XXXXPatchControl对应的Class对象,从而保证patch设置的状态成功;

加载补丁dex并修改oldClass中静态变量的对象

三、通过上面的逻辑梳理,基本可以确定Robust逻辑是这样的:

1、在编译时候通过Gradle插件或者AOP对每一个类的每个方法进入了代码插桩,插入固定的一段代码,并给每一个类都添加一个ChangeQuickRedirect静态变量;

2、通过对需要fix的方法增加注解,然后生成Patch补丁,补丁中包含三个类:

- PatchesInfoImpl:包含oldClass类名以及patchClass类名,放入集合;

- XXXXPatch:fix之后的方法放进了这个类,不会处理其他逻辑;

- XXXXPatchControl:实现了ChangeQuickRedirect接口,其实是XXXXPatch类的代理,重写isSupport和accessDispatch方法,在accessDispatch方法中会进入XXXXPatch类的fix之后的方法;

3、启动apk之后,下发patch补丁,使用类加载器加载补丁,同时读取PatchesInfoImpl类中的oldClass以及PatchClass,修改oldClass中的ChangeQuickRedirect变量,指向为XXXXPatchControl对象;

4、走到等待fix的方法时,因为此方法待fix,所以会直接走进ChangeQuickRedirect的实现类XXXXPatchControl类,同时执行对应的accessDispatch方法,从而最终执行XXXXPatch的对应方法。

其实官方图画的相当清楚:

官方Robust图

四、虽然整体的流程大概明白,但是其中有很多疑问没有解决:

1、如何插桩那一段代码?(ASM ?Javassist?)

2、补丁如何自动生成?

3、如何能够准确找到每一个方法?以及下面这一句代码的具体含义?

原始代码:

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

推荐阅读更多精彩内容