Skip to main content

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/SwitchesSupported scope
Android system version5.0 ~ 16
minSdkVersion21 ~ 28
Android Gradle Plugin3.5 ~ 8.x
R8 SupportSupports

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 annotationProcessor to kapt

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 @ApplicationProxy annotation on the existing Application of the business, and fill in the automatically generated Application class name
  • Step 2: Add the Application generated by the annotation to AndroidManifest.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 Application of the business to inherit from DefaultRFixApplicationLike
  • Step 2: Use the @ApplicationLike annotation on the class and fill in the automatically generated class name of Application
  • Step 3: Add the Application generated by the annotation to AndroidManifest.xml
  • Part 4: Solve various compilation and access exceptions caused by Application switching
// 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.

Hotfix Debug Page

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 generated
  • R.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 generated new.apk may run into a crash. At this time, you can try to remove the applyMapping parameter configured in build.gralde and 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.

Shiply Hotfix Sample Application

Was this page helpful?