Robust 2.0:支持Android R8的升级版热修复框架

适配R8:美团Robust热修复框架的优化与改进
本文介绍了美团的Android热修复框架Robust在适配R8优化工具时面临的问题和解决方案,包括改动识别、内联处理、混淆问题以及其他的优化措施,旨在确保补丁制作的准确性和效率。通过对构建过程的理解和字节码技术的应用,Robust实现了在R8环境下的稳定热修复。

2016年,我们对美团Android热更新方案Robust的技术原理做了详细介绍。近几年,Google 推出了新的代码优化混淆工具R8,Android 热修复补丁制作依赖二次构建包和线上包对比,需要对Proguard切换到R8提前进行适配和改造,本文分享 Robust 在适配 R8 以及优化改进中的一些思路和经验,希望能对大家有所帮助或者启发。

  • 1. 背景

  • 2. 主要挑战

  • 3 解决思路

    • 3.1 整体方案介绍

    • 3.2 问题和解决方法

  • 4 总结

  • 5 本文作者

 1. 背景 

美团 Robust 是基于方法插桩的实时热修复框架,主要优势是实时生效、零 Hook 兼容所有 Android 版本。2016 年,我们在《Android 热更新方案 Robust》一文中对技术原理做了详细介绍,主要通过给每个方法插入 IF 分支来动态控制代码逻辑,进而实现热修复。其核心主要有两部分:一个是代码插桩,一个是自动补丁。

  • 代码插桩这部分随着 Javassist、ASM 工具的广泛使用,整体方案比较成熟了,迭代改进主要是针对插桩代码体积和性能的优化;

  • 自动补丁这部分在实际使用过程中一直在迭代,跟业界主流热修复方案一样,自动化补丁工具作制作时机是在 Proguard 混淆之后,由于 Proguard 会对代码进行代码优化和混淆处理,在 Proguard 后制作补丁能够降低补丁生成的复杂性。

近年来, Google 推出了新的代码优化混淆工具 R8,用于取代第三方的代码优化混淆工具 Proguard,经过多年功能迭代和缺陷改进,R8 在功能上基本可以替代 Proguard,在结果上更为出色(优化生成的 Android 字节码体积更小)。Google 已经在新版本的构建工具中强制使用 R8 ,国内外已有多个知名 App 完成了 R8 适配并上线,比如微信 Android 在今年正式从 Proguard 切换到了 R8(通过升级 Android 构建工具链)。Android 热修复补丁制作依赖二次构建包和线上包对比,需要对 Proguard 切换到 R8 提前进行适配和改造,本文分享了美团平台技术部 Robust 在适配 R8 以及优化改进中的一些思路和经验。

2. 主要挑战 

Android 热修复补丁的大致制作流程:首先基于线上代码进行逻辑修复并二次打包,然后补丁生成工具自动比较修复包和线上包的差异,最后制作出轻量的补丁包。因此在补丁制作的过程中,需要解决两个主要问题:

  • 对于没有变动的代码,如何在二次打包时保证和线上包一致;

  • 对于本次修复的代码,如何在经过编译、优化、混淆之后准确识别出来并生成补丁代码。

要解决这两个问题,需要对 Android 编译和构建过程有一定了解,弄清楚问题产生的原因。下图 1 是一个 Android 项目从源码到 APK(Android 应用安装包)的构建过程(椭圆形对应构建工具链):

29c0019a64df43c456a51e83ab46854f.png图1 从源码到 APK 的构建过程

上图有些工具已被新出现的工具所取代,但是整体的流程并没有太大变化。对照这个图,我们分析一下其中对补丁制作/二次打包有影响的几个环节:

  1. 资源编译器(aapt/aapt2):资源编译环节会生成一个 R.java 文件(记录着资源 id,便于代码中引用),一般为了解决 R field 过多以及减少包大小,大型 Android 项目会在构建过程中会将资源 id 直接内联到调用处(发生在 javac 和 proguard 之间)。如果前后两次打包出现资源 id 不一致,会影响 diff 识别的结果。

  2. 代码编译器(javac):Java 代码经过 javac 编译成字节码之后,除了有一些简单的优化(如常量表达式折叠、条件编译),还有一些基础的脱糖(Java 8 之前的语法特性)操作会生成一些新的类/方法/指令,如匿名内部类会被编译成一个名为 OuterClass$1.class 的新类,以及命名为 access$200 之类的桥方法。如果改动涉及内部类、泛型,二次打包$后面的数字编号可能和线上包出现乱序。

  3. 代码优化器(ProGuard/R8):目前主要使用第三方开源工具 ProGuard (Google 推出 R8 计划取代 Proguard),通过 30+ 可选优化项,对前面生成的 Java 字节码进一步压缩、优化、混淆,可以使得 Android 安装包更小、更加安全、运行效率更高:

  • 压缩:通过静态分析并删除未被使用的 class/field/method,即源码中存在的 class/field/method,线上包中不一定存在。

  • 优化:通过一系列优化算法或者模版,对字节码进行优化,使得构建产物更小、运行更高效/安全,优化手段有合并类/接口、内联短方法、裁剪方法参数、删除不可达分支、外联代码(R8 新增)、删除无副作用代码(如 Log.d())、修改方法/变量可见性等等。优化后的字节码相比源码,可能出现 class/field/method 数量减少、field/method 访问修饰符发生变化、method 签名发生变化、code 指令变少,另外二次构建优化结果可能和线上包不一致。

  • 混淆:通过将 class/field/method

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值