Skip to main content

HarmonyOS

Last updated 09/03/2026
tip

The HarmonyOS SDK requires DevEco Studio 4.0+ and HarmonyOS API 10+, and depends on ThinkingData Analytics SDK 1.8.1+ (the release package declares a dependency on 1.9.0).

Latest version: v1.0.0

Update time: 2026-07-22

Downloads: Download

1. Overview​

Starting from AE 4.4, the Engage module provides the Config Center feature, which lets you add feature parameter configurations in the AE backend and pull them to your app through the client SDK, so you can finely customize your interactions with players.

This article describes how to integrate the HarmonyOS client SDK (@thinkingdata/remoteconfig). On the app side, you only need to handle interactions with the ThinkingData SDK and don't need to care about configuration details in the AE backend. The API and architecture are aligned with Android tdremoteconfig v1.3.0.

2. Integration​

The Config Center HarmonyOS SDK depends on the following ThinkingData SDKs:

SDK nameOverviewVersion requirement
@thinkingdata/analyticsCollects and processes data>= 1.9.0
@thinkingdata/remoteconfigFetches configuration from the AE backend>= 1.0.0

2.1 Install with ohpm (recommended)​

ohpm install @thinkingdata/remoteconfig
# or
ohpm i @thinkingdata/remoteconfig

You can also declare the dependency in the oh-package.json5 file of the host module and then run the installation:

{
"dependencies": {
"@thinkingdata/remoteconfig": "1.0.0"
}
}
ohpm install

2.2 Integrate a local HAR (development / debugging)​

{
"dependencies": {
"@thinkingdata/remoteconfig": "file:../TDRemoteConfig.har",
"@thinkingdata/analytics": "file:../TDAnalytics.har"
}
}
//Run
ohpm install

3. Initialization​

You must initialize the ThinkingData Analytics SDK before you initialize RemoteConfig.

3.1 Basic initialization​

import { TDAnalytics } from '@thinkingdata/analytics';
import { TDRemoteConfig } from '@thinkingdata/remoteconfig';

// Initialize the TA SDK first
await TDAnalytics.init(context, 'YOUR_APP_ID', 'YOUR_SERVER_URL');

// Then initialize RemoteConfig
TDRemoteConfig.enableLog(true); // Recommended during development
TDRemoteConfig.init(context, 'YOUR_APP_ID', 'YOUR_SERVER_URL');

3.2 Initialize with TDRemoteConfigSettings (recommended)​

import {
TDRemoteConfig,
TDRemoteConfigSettings,
TDRemoteConfigMode
} from '@thinkingdata/remoteconfig';

const settings = new TDRemoteConfigSettings();
settings.appId = 'YOUR_APP_ID';
settings.serverUrl = 'YOUR_SERVER_URL';
// settings.templateCode = 'TEMPLATE_CODE'; // Specify this when there are multiple templates; leave it empty by default

// Optional: Debug mode (skips cache control, which makes sending tests easier)
// settings.mode = TDRemoteConfigMode.DEBUG;

// Optional: custom fetch parameters carried during initialization
settings.customFetchParams = { platform: 'harmonyos' };

// Optional: custom bucket ID (for A/B experiments)
settings.customBucketId = { experiment_key: 'bucket_a' };

// Initialization callbacks (a fetch is triggered automatically once during init)
settings.setFetchTask({
onLocalCacheReady: () => {
// The local cache is ready; you can safely read the last successfully fetched configuration
},
onSuccess: () => {
// This network fetch succeeded
},
onFailure: (code: number, error: string) => {
// This network fetch failed
}
});

TDRemoteConfig.init(context, settings);

Callback trigger sequence:

  1. onLocalCacheReady(): Triggered immediately after the disk cache finishes loading (only when a cache exists)
  2. A network fetch is then initiated: onSuccess() is called if it succeeds, and onFailure() is called if it fails

4. Usage​

4.1 Sample data structure​

"configId" : {
"templateId" : [
{
"#strategy_id" : "2024121001",
"paramater_x" : "1111",
"#ops_receipt_properties" : {}
}
],
"#custom_params" : {

}
}

Where:

  • configId: The Config ID created in the Config Center module of the Engage backend, used to identify the business module. For details about config items, see Config items
  • templateId: The Template ID that you add under Config Items, used to identify the specific feature module. For details about config templates, see Config templates
  • #strategy_id: The unique ID of the strategy, used for strategy lifecycle management. For details about config strategies, see Config strategies
  • paramater_x: A config template parameter, corresponding to a configuration parameter required by the feature module
  • #ops_receipt_properties: Used for event receipt statistics. When you need to automatically measure strategy effects (not supported yet), receipt events must carry this property
  • #custom_params: Custom parameters on the client config channel. You can define the user property information to be carried to the client.

4.2 Set local default values​

You can set default values for config items in the TDRemoteConfig SDK. When a config item hasn't been added on the AE server, or the remote value hasn't been fetched locally, the SDK gets the local default value.

Set directly​

TDRemoteConfig.setDefaultValues({
welcome_message: 'Hello',
max_retry: 3,
feature_enabled: false
} as Record<string, Object>, 'YOUR_APP_ID');

Clear default values​

TDRemoteConfig.clearDefaultValues('YOUR_APP_ID');

4.3 Get values​

Get the content of the released and online strategies of a certain type under a config item:

const array = TDRemoteConfig.getData()
.get('configId')
.get('templateId')
.arrayValue();

You can also read values by field type:

const data = TDRemoteConfig.getData('YOUR_APP_ID');

const welcome: string = data.get('welcome_message').stringValue();
const maxRetry: number = data.get('max_retry').numberValue();
const enabled: boolean = data.get('feature_enabled').booleanValue();
const uiConfig: Record<string, Object> = data.get('ui_config').objectValue();

Where:

Value resolution rules​

How the value of a key is resolved:

  • The remote config value for the key is used first
  • If the key isn't configured remotely, the local default value for the key is used
  • If the key has no local default value either, an empty value is returned (the empty value of the corresponding type; no exception is thrown)

4.4 Fetch proactively​

TDRemoteConfig.fetch('YOUR_APP_ID')
.onSuccess(() => {
const value = TDRemoteConfig.getData('YOUR_APP_ID').get('key').stringValue();
})
.onFailure((code: number, error: string) => {
// Fetch failed
});

fetch() is protected by frequency control, so multiple calls within a short time don't send repeated network requests. To force a fetch, initialize the SDK in TDRemoteConfigMode.DEBUG mode.

4.5 Listen for updates​

You can add a notification listener for successful config fetches either before or after you initialize the SDK:

TDRemoteConfig.addConfigFetchListener({
onFetchSuccess: (statusData: Record<string, Object>) => {
// Config fetched successfully
}
});

Notification name​

onFetchSuccess (config fetched successfully)

Parameters carried by the notification​

tip

By default, the notification carries the statuses of strategies that changed to suspended (suspend) or forced offline (force_offline) between the previous request and this request. You can use them as your business requires. If you don't need them, ignore them.

Get the notification parameters as follows:

const map = statusData['strategy_status_map'] as Record<string, Object>;

The following example shows the corresponding value structure. It describes the status of the strategy whose ID is 20241209 in the config item template:

{
"configId" : {
"templateId" : {
"20241209" : "suspend"
}
}
}

4.6 Custom fetch parameters and Client Params​

Custom fetch parameters are appended to every fetch request:

TDRemoteConfig.setCustomFetchParams({
user_level: 'vip',
region: 'cn'
}, 'YOUR_APP_ID');

TDRemoteConfig.removeCustomFetchParam('user_level', 'YOUR_APP_ID');

Client Params are persisted locally and reported with every fetch:

TDRemoteConfig.addClientParams({ login_count: 5, vip_level: 2 });
TDRemoteConfig.accumulateNum('launch_count', 1);
const all = TDRemoteConfig.getClientParams();
TDRemoteConfig.removeClientParam('vip_level');

4.7 Switch accounts​

login / logout / setDistinctId in the TA SDK automatically trigger a refetch of the remote config (the SDK listens for identity changes internally). When the app returns to the foreground, the SDK also automatically checks for identity changes.

import { TDAnalytics } from '@thinkingdata/analytics';

TDAnalytics.login('user_account_id');
TDAnalytics.logout();
TDAnalytics.setDistinctId('new_distinct_id');

5. Send Test​

To quickly verify that the integration works and that config strategies are valid, the SDK supports a test mode.

const settings = new TDRemoteConfigSettings();
settings.mode = TDRemoteConfigMode.DEBUG;
settings.appId = 'YOUR_APP_ID';
settings.serverUrl = 'YOUR_SERVER_URL';
TDRemoteConfig.init(context, settings);

After Debug mode is enabled on the client, the client fetches configurations at the pace of test strategies. In the AE Engage module, you can create template tests or strategy tests. While waiting for the configuration to be fetched, you can watch the progress nodes on the frontend page.

For details, see the client Send Test section in Config templates.

Send tests for the client SDK require test devices. You can select or add test devices in the test device list.

During development, you can also enable SDK logs to make troubleshooting easier:

TDRemoteConfig.enableLog(true);
hdc shell hilog -T TDRemoteConfigSDK
Was this page helpful?