Android 热修复之DexPatch 介绍

Android 热修复之DexPatch 介绍

1. 方案介绍

为了解决Native模块上线后的问题,mPaas[1] 提供了热修复功能,实现不发布客户端apk场景下的热修复。目前Android端热修复主要包括andfix和dexpatch,考虑到andfix的版本兼容性,目前主要推荐使用DexPatch。
DexPatch修复原理比较简单,就是在启动后通过RPC拉取当前需要下发的jar包地址,然后通过独立进程去下载jar包文件,下载完成后保存。在二次启动的时候hook系统的classLoader,修改DexPathList, 在其数组的最前面加入一个有修改过的class的dex文件,使其拦截住数组后面的dex文件中同名的class的加载。如下图所示,classloader就会优先加载Patch.dex中的Ding.class,而忽略Classes.dex中的Ding.class, 达到了替换的效果。

Android 热修复之DexPatch 介绍
图1

基于这样的原理,DexPatch具有以下特征:
1.支持范围:是基于类级别的替换,所以只支持Java模块的patch,不支持非Java模块的patch,比如so模块。
2.兼容性:由于代理了系统的ClassLoader,使用的黑科技较少,所以整体方案兼容性较好。
3.生效时效性:只能在下载patch重启后才能生效,不支持实时生效。
4.成功率:由于使用独立进程下载,减少了启动阶段主进程闪退对patch下载的影响,提升了下载的成功比例。

2. 使用介绍

简单介绍在mPaas使用DexPatch模块的主要步骤以及问题排查思路,方便开发者日常使用。

2.1 触发patch拉取

启动阶段调用MPHotpatch.init(), 主要触发Patch信息的RPC请求,如果命中发布Patch发布规则,RPC会返回Patch的jar包下载地址,客户端去触发下载,下载后保存在客户端私有目录/data/user/0/包名/dexpatch/patch/ 下。

Android 热修复之DexPatch 介绍
图2

2.2 代码操作演示

以组件化模式接入为例,简单介绍Patch发布的主要流程。

2.2.1 代码改动前

Android 热修复之DexPatch 介绍
图3

需要保存改动前的构建产物,方便后续做Patch生成,地址在:build/intermediates/bundle/xxxx-raw.jar

2.2.2 代码改动后

Android 热修复之DexPatch 介绍
图4

重新编译,保存构建产物,产物地址:build/intermediates/bundle/xxxx-raw.jar

2.2.3 生成白名单配置

主要在热修复包时用于指定修复的类,配置文件为 .txt 格式,该配置文件应按顺序包含以下信息:
需要 Patch 的类。以 L 开头,后缀混淆后真实类名。如果多个类,每行只可写一个。 示例:Lxxx.xxx.clazzX
设置 Patch 类型为 dexpatch, 示例:PatchType: dexpatch
设置是否为静态Bundle。默认为 false,如果是静态链接的Bundle,需要设置为true。 示例:HostDex: true。目前mPaas客户端的模块一般都在静态链接里,一般写true。

Android 热修复之DexPatch 介绍
图5

2.2.4 查看签名

生成patch需要用到项目的打包秘钥,需要提前准备好,可以在打包脚本下找到对应的配置。

Android 热修复之DexPatch 介绍
图6

2.2.5 生成patch

① 通过mPaas自带的ide工具,点击热修复,进入修复页面。

Android 热修复之DexPatch 介绍
图7

② 按照页面提示,填入修复前和修复后的jar包地址,及白名单配置文件,勾选dexPatch,单击next。

Android 热修复之DexPatch 介绍
图8

③ 选择打包的配置文件,点击完成生成patch文件。

Android 热修复之DexPatch 介绍
图9

2.2.6 生成patch产物

生成patch产物如下:

Android 热修复之DexPatch 介绍
图10

查看产物,可以使用dex2jar工具反解diff.dex文件,使用jd-gui文件查看反解产物是否符合预期。

Android 热修复之DexPatch 介绍
图11

反解后可以看到修改的模块:

Android 热修复之DexPatch 介绍
图12

2.2.7 上传发布

① 选择上一步的产物jar包进行上传。

Android 热修复之DexPatch 介绍
图13

② 上传后可以通过白名单进行发布,验证patch的稳定性。

Android 热修复之DexPatch 介绍
图14

2.2.8 验证下载

白名单发布后,启动客户端,搜索关键字:DynamicRelease,可以看到在tool进程有触发下载的日志打出。需要说明的是,触发patch的下载是在tool进程,不在主进程的主要原因是怕主进程因启动重复闪退,导致patch下载失败,单独在tool进程下载,提高patch的下载成功比例。

Android 热修复之DexPatch 介绍
图15

查看下载目录,确认是否下载保存成功,下载目录在:
/data/user/0/包名/dexpatch/patch/20201023110012@20201023110012.jar

Android 热修复之DexPatch 介绍
图16

2.2.9 关掉进程重启

确认下载保存成功后,关掉App,重启查看是否生效,重启可以搜索关键字:DexPatchManager,查看patch生效的日志,日志会打印当前是否存在patch以及patch是否加载的日志。

Android 热修复之DexPatch 介绍
图17

同时我们也可以就实际业务场景进行验证,查看是否生效。

3. 常见问题

  1. aar模式集成后patch没生效
    aar模式集成时,需要继承框架的QuinoxlessApplication,指定Application为框架的实现类才能实现dexpatch的加载。QuinoxlessApplication内主要封装了dexpatch模块的初始化和加载。
  2. 使用加固后不生效
    需要使用加固前的apk生成patch,不能使用加固后的包生成patch。 然后仍需验证在不同加固厂商下的兼容表现。
  3. 使用热修复后,和 RPC 有关的调用发生 apache http 相关的 crash。
    请使用 Android 官网上的方式引入 apache http client,禁止使用导入 jar 包或者 gradle implementation/compile 的方式导入 http client。否则会引起 classloader 加载类混乱。
    建议方式:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>

参考文档

[1] mPaaS平台:https://www.aliyun.com/product/mobilepaas/mpaas

我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术,您可用钉钉扫描下方二维码,加入阿里云SRE技术学院钉钉圈子,和更多云上人交流关于云平台的那些事。

Android 热修复之DexPatch 介绍

上一篇:ECS训练营-DAY1分享(如何安装vsftpd)


下一篇:自建裸金属实例Oracle RAC上云