Skip to main content

Shiply Harmony 远程资源 SDK 集成

一、隐私安全说明

SDK 名称:Shiply Harmony SDK
版本:1.1.17
包名:shiply
更新时间:2025-09-04
MD5值:837a76c44a9fd1741f2ebde4f5f47bcd
SDK介绍:为移动开发者提供专业的资源分发能力,帮助开发者动态下载远程资源文件。
服务提供方:深圳市腾讯计算机系统有限公司
接入指引:《Shiply资源发布SDK接入指引》
隐私保护规则:《Shiply资源发布SDK个人信息保护规则》
合规使用指南:《Shiply资源SDK合规使用指南》

前置概念:接入前请先阅读 通用概念,了解各平台共用的 appId/appKey/userId/deviceId/target/资源加载策略 等核心概念,避免跨平台混淆。

二、Harmony SDK 简介

Shiply Harmony 版本 SDK,支持在鸿蒙系统上进行远程配置下发、远程资源下发。

  • 支持丰富的下发条件(允许自定义条件)

  • 支持灰度发布、全量发布、定时发布

  • 支持测试、验证、发布审批等流程

  • 差量省流技术(iOS/Android 支持,鸿蒙版本后续支持)

三、使用资源下发 SDK

请先参考:集成 ShiplyPro Harmony SDK 完成 SDK 集成

初始化 SDK

import { ResHubParam, ResHubModel, ResHubError, ResHub } from '@ohos/shiply'
let param: ResHubParam = new ResHubParam();
param.appVersion = "1.0.0";
param.deviceType = "Macbook";
param.systemVersion = "13.2.1";
param.qimei = "59521F70-C388-486B-A6A5-22B903E6DACD";
param.isDebugPackage = false; // 是否为Debug包,设置为 true 可获取到未发布的资源,默认为 false(仅用于测试,请注意不要在线上版本设置true!!!)
param.callbackOnMainThread = true;
let context = getContext(this) as common.UIAbilityContext;
let filesDir = context.filesDir;
param.resConfigStoragePath = filesDir + "/reshub/mmkv"; // 资源的配置文件存储目录
param.resStoragePath = filesDir + "/reshub/resource"; // 资源文件存储目录
let levelLogCallback = (level: number, log: string) => {
// 需要打印到你的 App 日志中!
};
// AppKey 和 AppID 请前往 Shiply 网页端获取
// 正式环境 “online”,测试环境 “test”
ResHub.initResHubCenter(param, "95b84b2e2d", "c3fb420e-d3e4-4711-90ea-4cdb7a81ac16", "online", levelLogCallback);
this.initMessage = "初始化成功";

异步拉取资源(的锁定版本)

资源加载策略:

  1. 如果本地有该资源或对应的可用预置资源,优先读取加锁的,如果当前没有加锁,则同时加锁该资源,通过block直接返回,并异步静默更新资源

  2. 如果本地没有该资源或对应的可用预置资源,则等待网络请求资源后,锁定版本并返回
    注意:
    该方法在进程运行期间,多次调用返回的资源保证是同一个版本

    /// @param resId 资源id
    /// @param progressBlock 进度的回调
    /// @param completedBlock 完成的回调
    let progressCalback = (progress: number) => {
    }
    let completionCallback = (success: Boolean, error: ResHubError, resModel: ResHubModel) => {
    hilog.info(0x0000, 'ShiplyLog', 'resId=%{public}s md5=%{public}s', resModel.resId, resModel.md5);
    }
    ResHub.loadWithId(this.resId, progressCalback, completionCallback);

同步获取现有最新资源

同步获取现有最新资源, 不会进行网络请求

 
资源加载策略:

  1. 如果本地没有获取过该资源,且没有对应的可用预置资源,返回nil

  2. 如果本地有该资源或对应的可用预置资源,返回最新版本的资源
    注意:

  3. 由于本地资源可能被更新,该方法多次调用返回的资源不保证是同一个版本

  4. 如果需要在进程运行期间获取特定资源时使用同一版本,可使用带版本锁定的接口

  5. 该方法默认会校验资源文件是否正确(MD5校验),如果需要关闭,请调用latestResWithId:needValidate:方法

    /// @param resId 资源id
    let resModel: ResHubModel = ResHub.latestResWithId(this.resId, true);

异步拉取本地配置中远程最新资源

资源加载策略:

  1. 返回自动更新配置策略下,配置中最新的资源,即使本地有可用资源,也会根据最新配置,先尝试获取最新包

  2. 如果本次更新失败,回调失败结果,并返回本地最新包

     
    注意:

  3. 由于获取的是最新资源,该方法多次调用返回的资源不保证是同一个版本

  4. 如果需要在进程运行期间获取特定资源时使用同一版本,可使用带版本锁定的接口

  5. 此处的最新包和平台的最新包不一定匹配,会有一定的延时,因为当前配置是根据自动更新策略全量拉取的,所以本次如果命中配置缓存,则不能获取到平台上的最新资源。
    如果需要拉取实时最新资源,请使用Realtime Latest相关接口

    /// @param resId 资源id
    /// @param progressBlock 进度的回调
    /// @param completedBlock 完成的回调
    let progressCalback = (progress: number) => {
    }
    let completionCallback = (success: Boolean, error: ResHubError, resModel: ResHubModel) => {
    hilog.info(0x0000, 'ShiplyLog', 'resId=%{public}s md5=%{public}s', resModel.resId, resModel.md5);
    }
    ResHub.loadLatestWithId(this.resId, progressCalback, completionCallback);

异步拉取远程实时最新资源

资源加载策略:

  1. 保证实时返回最新资源,即使本地有可用资源,也会先请求最新配置,再根据配置获取最新包

  2. 如果本次更新失败,回调失败结果,并返回本地最新包

     
    注意:

  3. 因为该接口一定会实时请求配置,频繁调用会大幅增加配置拉取成本,因此只应该对实时性要求非常高,要求必须拉到远端最新包的资源调用该接口

  4. 对实时性要求不太高,又希望更新的资源,请调用loadLatest(异步拉取多个本地配置中 远程最新资源)接口,该接口默认冷启动后,以及每三小时定时更新配置

  5. 由于获取的是最新资源,该方法多次调用返回的资源不保证是同一个版本

  6. 如果需要在进程运行期间获取特定资源时使用同一版本,可使用带版本锁定的接口

    /// @param resId 资源id
    /// @param progressBlock 进度的回调
    /// @param completedBlock 完成的回调
    let progressCalback = (progress: number) => {
    }
    let completionCallback = (success: Boolean, error: ResHubError, resModel: ResHubModel) => {
    hilog.info(0x0000, 'ShiplyLog', 'resId=%{public}s md5=%{public}s', resModel.resId, resModel.md5);
    }
    ResHub.loadRealtimeLatestWithId(this.resId, progressCalback, completionCallback);

异步拉取资源的最新配置

配置加载策略:

  1. 该方法仅获取配置,不下载/更新资源

  2. 结果回调返回的资源中,本地存储路径信息为空

    /// @param resId 资源id
    /// @param completedBlock 完成的回调
    let completionCallback = (success: Boolean, error: ResHubError, resModel: ResHubModel) => {
    hilog.info(0x0000, 'ShiplyLog', 'resId=%{public}s md5=%{public}s', resModel.resId, resModel.md5);
    }
    ResHub.fetchResConfigWithId(this.resId, completionCallback);

删除本地指定id的资源

/// @param resId 资源id
ResHub.deleteWithId(this.resId);

清空本地所有资源

ResHub.deleteAll();

ResHubModel 完整字段表

字段类型说明
resIdstring资源 ID
versionnumber版本号
sizenumber文件大小
md5string文件 MD5
innerMd5MapMap\<string, string>内部文件 MD5 映射
downloadUrlstring下载地址
fileExtrastring文件附加信息
noNeedUnZipboolean是否需要解压
localPathstring本地路径
sourceRelativeLocalPathstring源文件相对路径
relativeLocalPathstring文件相对路径
sourceLocalPathstring源文件本地路径
timestampnumber时间戳
isPresetResourceboolean是否预置资源
taskIdstring任务 ID
taskDescriptionstring任务描述

ResHubModel 方法

  • getLocalPath(): string — 返回 _getLocalPathlocalPath(C++ NAPI 预计算)
  • getSourceLocalPath(): string — 返回 _getSourceLocalPathsourceLocalPath

回调监听

ResHub.onResFirstLoaded((resId, model) => {});     // 资源首次加载
ResHub.onResRefreshed((resId, model) => {}); // 资源刷新
ResHub.onAllConfigsPulled((configMap) => {}); // 全部配置拉取完成
ResHub.onConfigDeleted((resIds: string[]) => {}); // 配置删除

Promise 方式加载

const model = await ResHub.asyncLoadWithId('my_res', (p) => {});

同步获取配置

const cfg = ResHub.fetchedResConfigWithId('my_res');

注意事项

  1. variantMap 必须转普通对象:ArkTS 传 Map 给 native 读不到,封装层内部已用 variantMapToPlainObject 转换;自定义扩展时注意传 Record 而非 Map。
  2. logger 传 null:走无日志模式,建议传业务回调。
  3. initResHubCenter 失败抛异常:参数非法或 native 初始化失败会 throw。
  4. 底层 C++:复杂场景参考 C++ 核心 API 文档。
  5. storagePath 必填resConfigStoragePath/resStoragePath 需可写目录。
  6. 无 remove/unregister 方法onResFirstLoadedonResRefreshedonAllConfigsPulledonConfigDeleted 是 set-only 操作。再次调用会覆盖之前的回调,而非追加。如果需要临时监听,在回调封装中自行管理 enabled 标志位。
  7. setCustomPropertyValue 参数顺序是 (value, key):value 在前,key 在后(如 setCustomPropertyValue('66668888', 'qqUin')),这与常见的 (key, value) 顺序相反。此设计在各层级一致(ArkTS / NAPI / C API / 核心类),使用时务必注意。

线程说明

ResHubParam.callbackOnMainThread 默认为 false

设置进度回调结果回调监听器回调
false(默认)后台线程后台线程后台线程
true主线程主线程主线程
  • false(默认):loadWithId/loadLatestWithId/loadRealtimeLatestWithIdonProgressonResult,以及监听器回调均在后台线程触发。消费者必须自行处理 ArkUI 线程安全。
  • true:上述所有回调统一派发到主线程,可直接操作 UI 状态。

配置拉取与上报

// 手动全量拉取资源配置
ResHub.updateAllConfigsWithCompleted((configMap: Map<string, ResHubModel>) => {});

// 上报
ResHub.reportResDownloaded(resId, taskId, version);
ResHub.reportResLoaded(resId, taskId, version);
ResHub.reportResPulled(resId, taskId, version);
ResHub.reportToShiply('my_event', { k1: 'v1' });

其他 API

ResHub.switchDeviceId('newQimei', () => {});    // 切换设备 ID
ResHub.setCustomPropertyValue('value', 'key'); // ⚠️ 参数顺序是 (value, key),不是 (key, value)!见下方注意事项第 7 条
ResHub.sdkVersion(); // 获取 SDK 版本号
这篇文档对您有帮助吗?