Shiply Hotfix Android SDK Integration Guide
1. Privacy and Security Instructions
Shiply Hotfix SDK
Version: 2.1.0
Update time: September 15, 2025
SDK introduction: Provide mobile developers with online hotfix capabilities to promptly solve serious online App problems.
Service provider: Shenzhen Tencent Computer Systems Co., Ltd.
Access Guide: Shiply Hotfix SDK Access Guide
Privacy Protection Rules: Shiply Hotfix SDK Privacy Protection Rules
2. Integrate the SDK
2.1 Supported scope
| Versions/Tools/Switches | Supported scope |
|---|---|
| Android system version | 5.0 ~ 16 |
| minSdkVersion | 21 ~ 28 |
| Android Gradle Plugin | 3.5 ~ 8.x |
| R8 Support | Supports |
2.2 Introducing compilation plug-in and runtime SDK
1. Introduce the hot Fixed gradle compilation plug-in into build.gradle in the project root directory
buildscript {
repositories {
maven { url "https://maven.cnb.cool/tencent-tds/shiply-public/-/packages//" }
}
dependencies {
classpath "com.tencent.rfix:RFix-gradle-plugin:2.1.0"
}
}
2. Introduce the hot Fixed runtime SDK and annotation processor into the build.gradle of the project app
repositories {
maven { url "https://maven.cnb.cool/tencent-tds/shiply-public/-/packages//" }
}
dependencies {
compileOnly "com.tencent.rfix:RFix-android-anno:2.1.0"
implementation "com.tencent.rfix:RFix-android-lib:2.1.0"
annotationProcessor "com.tencent.rfix:RFix-android-anno:2.1.0"
}
PS: If the annotation does not take effect normally during compilation and the annotation target class is written in kotlin, you can try changing
annotationProcessortokapt
3. Apply the gradle compilation plug-in in build.gradle of the project app and make relevant configurations
apply plugin: 'com.tencent.rfix'
RFixPatch {
// Patch type: Disable/Tinker
patchType = 'Tinker'
// Target APK to patch; usually the Release build shipped to users
oldApks = ["${projectDir.absolutePath}/RFix/old.apk"]
// Patched APK built after modifying code on top of the target version
newApks = ["${projectDir.absolutePath}/RFix/new.apk"]
// Patch output directory
outputFolder = "${projectDir.absolutePath}/RFix/"
// Ignore warnings during patch compilation (use with caution; ignored warnings may produce invalid patches)
ignoreWarning = false
buildConfig {
// Unique patch ID for the APK; used to verify patch/APK compatibility
patchId = new Date().format("MMddHHmmss")
// Enable when building multiple architectures with splits so each APK gets a unique PatchId
appendOutputNameToPatchId = true
// ProGuard mapping and resource ID mapping files for the target APK
applyMapping = "${projectDir.absolutePath}/RFix/old_mapping.txt"
applyResourceMapping = "${projectDir.absolutePath}/RFix/old_R.txt"
// Enable independent packaging for multi-architecture patches
enablePackageSeparate = false
// Enable patch build mode for hardened/protected apps
isProtectedApp = false
}
}
2.3 Transform Application and initialize SDK
Since the hot Fixed engine needs to load patches before the application starts, it needs to take over the Application of the App, which requires the developer to modify the Application of the App.
Here we provide two transformation solutions, developers can choose one according to their own needs.
Option 1: Automatic agency business application (recommended)
This solution is the easiest to access and has the smallest modification cost, and is compatible with dependency injection frameworks such as Hilt and scenarios where the existing Application inheritance relationship of the business cannot be modified.
- Step 1: Use the
@ApplicationProxyannotation on the existingApplicationof the business, and fill in the automatically generatedApplicationclass name - Step 2: Add the
Applicationgenerated by the annotation toAndroidManifest.xml - Step 3: Initialize the SDK at the appropriate time, and initialize the Supports to execute asynchronously in the child thread.
// The annotation auto-generates a proxy Application in the target class package.
// Manually register this proxy Application in AndroidManifest.xml
@ApplicationProxy(application = ".SampleProxyApplication")
public class SampleApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialize RFix
initRFix();
}
private void initRFix() {
// 1. Initialize the logging interface to receive SDK internal logs
RFixLog.setLogImpl(new CustomRFixLog());
// 2. Build RFix business parameters
RFixParams params = new RFixParams("your_app_id", "your_app_key")
.setDeviceManufacturer(Build.MANUFACTURER) // Device manufacturer for delivery rule matching
.setDeviceModel(Build.MODEL) // Device model for delivery rule matching
.setUserId("123456") // User ID for delivery rule matching
.setCustomProperty("property1", "xxx"); // Custom property to extend delivery rules
// 3. Initialize RFix
RFixApplicationLike applicationLike = DefaultRFixApplicationLike.createApplicationLike(this);
RFixInitializer.initialize(applicationLike, params);
}
}
Option 2: Transform the business Application to ApplicationLike (Tinker standard access method)
This solution requires developers to modify the existing Application, which is relatively intrusive and costly.
After the transformation, the way to obtain Application in the original code will change, and it must be obtained through the getApplication() method of the ApplicationLike object.
- The first step: directly change the existing
Applicationof the business to inherit fromDefaultRFixApplicationLike - Step 2: Use the
@ApplicationLikeannotation on the class and fill in the automatically generated class name ofApplication - Step 3: Add the
Applicationgenerated by the annotation toAndroidManifest.xml - Part 4: Solve various compilation and access exceptions caused by
Applicationswitching
// The annotation auto-generates an Application in the target class package.
// Manually register this Application in 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);
// Initialize RFix
initRFix();
}
private void initRFix() {
// 1. Initialize the logging interface to receive SDK internal logs
RFixLog.setLogImpl(new CustomRFixLog());
// 2. Build RFix business parameters
RFixParams params = new RFixParams("your_app_id", "your_app_key")
.setDeviceManufacturer(Build.MANUFACTURER) // Device manufacturer for delivery rule matching
.setDeviceModel(Build.MODEL) // Device model for delivery rule matching
.setUserId("123456") // User ID for delivery rule matching
.setCustomProperty("property1", "xxx"); // Custom property to extend delivery rules
// 3. Initialize RFix
RFixInitializer.initialize(this, params);
}
}
2.4 Integrated hot Fixed debugging page
In order to facilitate developers to debug the function of the patch during the development stage, a simple debugging page AbsRFixDevActivity is built into the SDK.
Developers can inherit this class when accessing and implement a simple patch debugging page.
public class RFixDevActivity extends AbsRFixDevActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
During development and debugging, we can actively trigger configuration pull through the debugging page and observe the installation results and loading status of the patch.

2.5 SDK other function descriptions
1. Actively trigger patch pull
When the SDK is initialized, a check of the remote patch configuration will be automatically triggered. If the patch status changes, subsequent downloading, installation, uninstallation, etc. will be automatically triggered.
If developers have special needs, they can also actively trigger remote patch configuration checks through the requestConfig interface at the appropriate time.
RFix manager = RFix.getInstance();
manager.requestConfig()
2. Monitor the patch installation process
If developers need to monitor the patch installation process, they can do so by registering a listener. Currently, the listener provides: callback interfaces for configuration pull, patch download, and patch installation.
PS: Developers can use the listener to actively restart the process when the patch is successfully installed for the first time to speed up the patch's effectiveness.
// Register callbacks during initialization to handle business logic at each stage
RFixInitializer.initialize(applicationLike, params, new RFixListener() {
@Override
public void onConfig(boolean success, int resultCode, PatchConfig patchConfig) {
// Handle config pull
// ...
}
@Override
public void onDownload(boolean success, int resultCode, PatchConfig patchConfig, String patchFilePath) {
// Handle patch download
// ...
}
@Override
public void onInstall(boolean success, int resultCode, RFixPatchResult patchResult) {
if (success && patchResult.isPatchSuccessFirstTime()) {
// Patch installed successfully; record a flag and restart the app when appropriate to apply the patch sooner
// ...
}
}
});
3. Make patch package
The use of hot Fixed is more complicated than other SDKs, and you may encounter more compilation problems during patch production, which requires developers to have a certain understanding of the Android compilation system.
The entire patch production process is divided into three links:
3.1 Build Fixed target old.apk (Release version to users)
After accessing the SDK, you only need to use the original build command of the project to package the Apk. At this stage, in addition to getting old.apk, we also need to save several intermediate files obtained during this build.
mapping.txt: code obfuscation mapping file, only the Release version will be generatedR.txt: Resource ID mapping file, both Debug/Release versions will be generated
The above files can be found in the following locations. After obtaining the file, we need to put it on the specified path according to the configuration in build.gralde.
// Back up mapping.txt
from "${buildDir}/outputs/mapping/release/mapping.txt"
into "${projectDir.absolutePath}/RFix/old_mapping.txt"
// Back up R.txt
// R.txt location varies across AGP versions
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 Build Fixed new.apk (code modified version)
After configuring old.apk and its related intermediate files, we can start to modify the code and build the Fixed new.apk. We also only need to use the original build command of the project for packaging.
After obtaining new.apk, we also need to put it on the specified path according to the configuration in build.gralde.
PS: For projects with R8 or higher AGP versions enabled, you may encounter R8-related errors when building
new.apk, or the generatednew.apkmay run into a crash. At this time, you can try to remove theapplyMappingparameter configured inbuild.graldeand repackage.
3.3 Build Fixed patch package patch.apk
After configuring old.apk, new.apk and their related intermediate files, we can execute ./gradlew RFixBuildRelease to trigger the construction of the patch package. After the build is successful, the patch package can be found in
Found under outputFolder, please use the signed version, because when the patch is installed, it will check whether the signatures of patch.apk and old.apk are consistent.
If some alarms are encountered during patch construction, causing patch construction to fail, you can also try to generate a patch by ignoring these alarms. However, ignoring alarms has certain risks and requires developers to fully evaluate them.
RFixPatch {
// Ignore warnings during patch compilation (use with caution; ignored warnings may produce invalid patches)
ignoreWarning = false
}
After the patch is successfully produced, the entire SDK access is basically completed. Next, developers can install old.apk on the device and distribute the patch package to the device through the Release platform for verification.
To release and verify the patch package through the Release platform, please refer to: How to use Android Hotfix
4. Hotfix sample application
If developers encounter something they do not understand during access, they can also refer to the hot Fixed sample application.
There are also some simplified access scripts in the example, which can be referenced when accessing.