Shiply 热修复 Android SDK 接入指引
一、隐私安全说明
Shiply 热修复 SDK
版本:2.0.1
更新时间:2025年2月21日
SDK介绍:为移动开发者提供在线热修复的能力,及时解决 App 线上严重问题。
服务提供方:深圳市腾讯计算机系统有限公司
接入指引:Shiply 热修复 SDK 接入指引
隐私保护规则:Shiply 热修复 SDK 隐私保护规则
二、接入 SDK
2.1 支持范围
版本 / 工具 / 开关 | 支持范围 |
---|---|
Android 系统版本 | 5.0 ~ 15 |
minSdkVersion | 21 ~ 28 |
Android Gradle Plugin | 3.5 ~ 8.x |
R8 Support | 支持 |
2.2 引入编译插件和运行时 SDK
1. 在项目根目录的 build.gradle
中引入热修复的 gradle 编译插件
buildscript {
repositories {
maven { url "https://tencent-tds-maven.pkg.coding.net/repository/shiply/repo/" }
}
dependencies {
classpath "com.tencent.rfix:RFix-gradle-plugin:2.0.1"
}
}
2. 在项目 app 的 build.gradle
中引入热修复的运行时 SDK 和注解处理器
repositories {
maven { url "https://tencent-tds-maven.pkg.coding.net/repository/shiply/repo/" }
}
dependencies {
compileOnly "com.tencent.rfix:RFix-android-anno:2.0.1"
implementation "com.tencent.rfix:RFix-android-lib:2.0.1"
annotationProcessor "com.tencent.rfix:RFix-android-anno:2.0.1"
}
PS: 如果编译时注解没能正常生效,注解目标类又是 kotlin 写的,可以尝试将
annotationProcessor
改为kapt
3. 在项目 app 的 build.gradle
中应用 gradle 编译插件,并进行相关配置
apply plugin: 'com.tencent.rfix'
RFixPatch {
// 补丁类型:Disable/Tinker
patchType = 'Tinker'
// 修复目标Apk,通常为对外发布的Release版本
oldApks = ["${projectDir.absolutePath}/RFix/old.apk"]
// 修复后的Apk,在目标版本基础上修改代码后的版本
newApks = ["${projectDir.absolutePath}/RFix/new.apk"]
// 补丁输出目录
outputFolder = "${projectDir.absolutePath}/RFix/"
// 忽略补丁编译中的告警信息(该功能谨慎开启,忽略某些告警后生成的补丁可能异常)
ignoreWarning = false
buildConfig {
// Apk的唯一补丁标识,用于识别补丁和Apk是否匹配
patchId = new Date().format("MMddHHmmss")
// 使用splits实现多架构编译时需要开启该功能,以确保每个Apk的PatchId不同
appendOutputNameToPatchId = true
// 修复目标Apk的代码混淆文件和资源ID映射文件
applyMapping = "${projectDir.absolutePath}/RFix/old_mapping.txt"
applyResourceMapping = "${projectDir.absolutePath}/RFix/old_R.txt"
// 开启多架构补丁独立打包功能
enablePackageSeparate = false
// 开启加固包的补丁构建模式
isProtectedApp = false
}
}
2.3 改造 Application 并初始化 SDK
由于热修复引擎需要在应用启动前进行补丁加载,因此需要接管 App 的 Application,这就需要开发者对 App 的 Application 进行改造。
这里我们提供了两种改造方案,开发者可以根据自身需求选择一种即可。
方案一:自动代理业务 Application(推荐)
该方案是接入最简单,改造成本最小的方案,并且兼容 Hilt
这类依赖注入框架,以及无法修改业务现有 Application
继承关系的场景。
- 第一步:对业务现有的
Application
使用@ApplicationProxy
注解,并填写自动生成Application
的类名 - 第二步:将注解生成的
Application
添加到AndroidManifest.xml
中 - 第三步:在合适的时机初始化 SDK,初始化支持在子线程异步执行
// 注解会自动在目标类所在包下生成代理 Applicaiton
// 该代理 Applicaiton 需要手动配置到 AndroidManifest.xml
@ApplicationProxy(application = ".SampleProxyApplication")
public class SampleApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 初始化RFix组件
initRFix();
}
private void initRFix() {
// 1. 初始化日志接口,用于接出SDK内部输出的日志
RFixLog.setLogImpl(new CustomRFixLog());
// 2. 构造RFix业务参数
RFixParams params = new RFixParams("your_app_id", "your_app_key")
.setDeviceManufacturer(Build.MANUFACTURER) // 设置设备厂商,用于下发规则控制
.setDeviceModel(Build.MODEL) // 设置设备型号,用于下发规则控制
.setUserId("123456") // 设置用户ID,用于下发规则控制
.setCustomProperty("property1", "xxx"); // 设置自定义属性,用于扩展下发规则
// 3. 初始化RFix组件
RFixApplicationLike applicationLike = DefaultRFixApplicationLike.createApplicationLike(this);
RFixInitializer.initialize(applicationLike, params);
}
}
方案二:改造业务 Application
为 ApplicationLike
(Tinker标准接入方式)
该方案需要开发者改造现有的 Application
,侵入性和改造成本都相对较高。
改造后原代码中获取 Application
的方式会发生变化,必须通过 ApplicationLike
对象的 getApplication()
方法获取。
- 第一步:将业务现有的
Application
直接改为继承自DefaultRFixApplicationLike
- 第二步:对该类使用
@ApplicationLike
注解,并填写自动生成Application
的类名 - 第三步:将注解生成的
Application
添加到AndroidManifest.xml
中 - 第四部:解决因
Application
切换导致的各处编译和访问异常
// 注解会自动在目标类所在包下生成 Applicaiton
// 该 Applicaiton 需要手动配置到 AndroidManifest.xml
@ApplicationLike(application = ".SampleApplication")
public class SampleApplicationLike extends DefaultRFixApplicationLike {
public SampleApplicationLike(Application application, RFixLoadResult loadResult) {
super(application, loadResult);
}
@Override
public void onBaseContextAttached(Context base) {
super.onBaseContextAttached(base);
// 初始化RFix组件
initRFix();
}
private void initRFix() {
// 1. 初始化日志接口,用于接出SDK内部输出的日志
RFixLog.setLogImpl(new CustomRFixLog());
// 2. 构造RFix业务参数
RFixParams params = new RFixParams("your_app_id", "your_app_key")
.setDeviceManufacturer(Build.MANUFACTURER) // 设置设备厂商,用于下发规则控制
.setDeviceModel(Build.MODEL) // 设置设备型号,用于下发规则控制
.setUserId("123456") // 设置用户ID,用于下发规则控制
.setCustomProperty("property1", "xxx"); // 设置自定义属性,用于扩展下发规则
// 3. 初始化RFix组件
RFixInitializer.initialize(this, params);
}
}
2.4 集成热修复调试页面
为了方便开发者在开发阶段对补丁的功能进行调试,SDK 中内置了一个简单的调试页面 AbsRFixDevActivity
,
开发者可以在接入时继承该类,实现一个简单的补丁调试页。
public class RFixDevActivity extends AbsRFixDevActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
在开发调试中,我们可以通过调试页面主动触发配置拉取,并观察补丁的安装结果和加载情况。

2.5 SDK 其他功能说明
1. 主动触发拉取补丁
在 SDK 初始化时会自动触发一次远端补丁配置的检查,如果补丁状态有变化,则会自动触发后续的下载、安装、卸载等行为。
如果开发者有特殊的需求,也可以在合适的时机,通过 requestConfig
接口主动触发远端补丁配置检查。
RFix manager = RFix.getInstance();
manager.requestConfig()
2. 监听补丁安装过程
如果开发者有监听补丁安装过程的需求,可以通过注册监听器来实现,目前监听器提供:配置拉取、补丁下载、补丁安装的回调接口。
PS: 开发者可以利用监听器,在补丁首次安装成功时,主动重启进程,以加速补丁的生效速度。
// 在初始化时可以注册回调,以便在各阶段处理业务逻辑
RFixInitializer.initialize(applicationLike, params, new RFixListener() {
@Override
public void onConfig(boolean success, int resultCode, PatchConfig patchConfig) {
// 处理配置
// ...
}
@Override
public void onDownload(boolean success, int resultCode, PatchConfig patchConfig, String patchFilePath) {
// 处理下载文件
// ...
}
@Override
public void onInstall(boolean success, int resultCode, RFixPatchResult patchResult) {
if (success && patchResult.isPatchSuccessFirstTime()) {
// 补丁安装成功,可以记录一个标记,并在合适的时机重启应用,以加快补丁生效速度
// ...
}
}
});
三、制作补丁包
热修复的使用相比其他 SDK 要复杂一些,补丁制作期间可能会遇到较多编译问题,这就需要开发者对 Android 的编译系统有一定的理解。
整个补丁制作过程分为三个环节:
3.1 构建修复目标 old.apk
(发布给用户的版本)
在接入 SDK 后,只需要使用项目原来的构建命令进行 Apk 打包即可, 这个阶段我们除了会得到 old.apk
以外,还需要保存本次构建得到的几个中间文件。
mapping.txt
:代码混淆的映射文件,只有 Release 版本会生成R.txt
:资源 ID 的映射文件,Debug/Release 版本都会生成
以上文件我们可以在下列这些位置找到。在获得文件后,我们需要按照 build.gralde
中的配置,将其放到指定的路径上。
// 备份 mapping.txt
from "${buildDir}/outputs/mapping/release/mapping.txt"
into "${projectDir.absolutePath}/RFix/old_mapping.txt"
// 备份 R.txt
// 不同AGP版本下的R.txt位置有差异
from "${buildDir}/intermediates/symbols/release/R.txt"
from "${buildDir}/intermediates/symbol_list/release/R.txt"
from "${buildDir}/intermediates/runtime_symbol_list/release/R.txt"
from "${buildDir}/intermediates/runtime_symbol_list/release/processReleaseResources/R.txt"
into "${projectDir.absolutePath}/RFix/old_R.txt"
3.2 构建修复后的 new.apk
(修改代码后的版本)
在配置好 old.apk
及其相关的中间文件后,我们就可以开始修改代码,构建修复后的 new.apk
了,同样只需要使用项目原来的构建命令打包即可。
在获得 new.apk
后,我们同样需要按照 build.gralde
中的配置,将其放到指定的路径上。
PS: 对于开启了 R8 或者 AGP 版本较高项目,在构建
new.apk
时可能遇到 R8 相关的报错,或者构建生成的new.apk
运行 Crash。这个时候可以尝试去掉build.gralde
中配置的applyMapping
参数并重新打包。
3.3 构建修复补丁包 patch.apk
在配置好 old.apk
、new.apk
及其相关的中间文件后,我们可以执行 ./gradlew RFixBuildRelease
触发补丁包的构建。构建成功后,补丁包可以在
outputFolder
下找到,请使用已签名的版本,因为补丁安装时会检查 patch.apk
和 old.apk
签名是否一致。
如果补丁构建中遇到一些告警,导致补丁构建失败,也可以尝试通过忽略这些告警来生成补丁,但是忽略告警有一定的风险,需要开发者充分评估。
RFixPatch {
// 忽略补丁编译中的告警信息(该功能谨慎开启,忽略某些告警后生成的补丁可能异常)
ignoreWarning = false
}
在成功制作出补丁以后,整个 SDK 接入就基本结束了。接下来开发者可以将 old.apk
安装到设备上,并通过发布平台将补丁包下发到设备上进行验证。
通过发布平台,对补丁包进行发布和验证,请参考:如何使用 Android 热修复
四、热修复示例应用
开发者在接入中如果有遇到一些不理解的地方,也可以参考热修复示例应用。
示例中也有一些简化的接入脚本,可以在接入时进行参考。