美文网首页
简单了解Robust(一)

简单了解Robust(一)

作者: _夜雨 | 来源:发表于2018-02-28 16:32 被阅读181次

因为工作需要,所以需要在公司项目中增加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反编译效果

相关文章

  • 简单了解Robust(一)

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

  • Robust使用篇

    Robust使用篇 Robust使用相对还是比较简单的.有一些坑可能官方文档里讲的不是那么详细,需要自己踏过去 使...

  • Robust热更应用在SDK项目

    美团Robust提供的的依赖只能应用在APP项目中,SDK项目要使用Robust必须简单的修改一下源码才能使用。在...

  • 2019-7-29每日一词

    Robust She looks robust and healthy enough.

  • CVPR 2018学习笔记(2018-07-02更新)

    workshop Robust vision challenge 2018robust vision.JPG 会议...

  • Robust接入简单说明

    准备 在APP的build.gradle文件中,添加依赖:apply plugin: 'com.android.a...

  • 每日一词222Robust

    1. 这是个什么词? 词:robust 英英释义:a robust system, organization et...

  • Day222-robust

    1. 这是个什么词? 词:robust 英英释义:a robust system, organization et...

  • 20190815 robust

    1. 这是个什么词? 词:robust 英英释义:a robust system, organization et...

  • robust

    场景:这是一家体系健康的公司。 造句:The company has a robust system.

网友评论

      本文标题:简单了解Robust(一)

      本文链接:https://www.haomeiwen.com/subject/exybxftx.html