一、项目背景
公司是一个比较大的数字园区,现在有几十个微信小程序在跑,包括停车找位、会议室预约、活动报名、园区约会等高频场景,现在要上线鸿蒙APP,领导希望能够把全部的小程序移植到鸿蒙APP里去。如果全部用HarmonyOS原生代码重写,人力成本和时间成本都难以接受。尤其是业务方部门的是"鸿蒙APP上线后功能与微信端完全一致",因此尝试使用小程序容器方案。
计划在原生APP里嵌入一个小程序运行时,现有小程序代码无需修改或少量修改,直接运行。接入成本低,迭代可以复用小程序现有的发布体系。
二、小程序容器技术原理
小程序容器方案的核心,是将微信小程序的双线程架构(逻辑层+渲染层分离)封装为一个可嵌入的SDK。业务代码运行在逻辑层,UI渲染由原生组件完成,两者通过消息队列通信。
对于开发者而言,感知不到线程切换------写小程序的体验和写原生APP基本一致。
FinClip在Harmony端提供了完整的SDK支持,包含核心运行时、扩展能力(地图/蓝牙/分享/日历等)以及配套的开发者工具。已有的小程序通过FinClip管理后台统一上下架,APP端通过SDK启动对应小程序即可。

三、集成路径与关键步骤
3.1 环境要求
集成SDK前需要确认环境版本:
- DevEco Studio:5.0.3.300及以上
- 鸿蒙系统版本:5.0.0(API 12)及以上,手机系统版本不低于3.0.0.22
项目启动前需要在FinClip后台创建应用并获取SDK KEY与SDK SECRET,后续初始化时需要填入。
3.2 添加项目依赖
SDK支持线上依赖和本地依赖两种方式。线上依赖需要在项目根目录创建.ohpmrc文件,配置OHPM仓库地址:
text
registry=https://ohpm.openharmony.cn/ohpm/
@finclip:registry=https://ohpm.finogeeks.com/repos/ohpm
然后在oh-package.json5中添加核心依赖:
json
"@finclip/sdk": "latest"
执行ohpm install完成安装。
如果需要离线集成,可以从FinClip官网下载SDK的HAR包,放到项目目录后以本地路径方式引用:
json
"@finclip/sdk": "file:../har/FinClipSDK.har",
"@finclip/share-sdk": "file:../har/FinClipShareSDK.har"
3.3 配置Ability
由于鸿蒙共享包无法注册Ability,需要宿主APP显式注册。不配置的话小程序无法正常启动。
在module.json5中配置:
json
{
"name": "AppletAbility",
"srcEntry": "./ets/appletAbility/AppletAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:app_icon",
"launchType": "specified",
"startWindowIcon": "$media:app_icon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"removeMissionAfterTerminate": true
}
launchType必须设为specified,否则同一个小程序无法同时打开多个实例。在数字园区场景下,用户可能在停车小程序和会议室预约小程序之间频繁切换,如果不支持多实例,体验会很差。
removeMissionAfterTerminate设为true可以确保小程序关闭后不在系统任务列表残留。
Ability的具体实现参考文档:
ts
import { FinAppClient } from '@finclip/sdk';
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class AppletAbility extends UIAbility {
onCreate() {}
onDestroy() {}
async onWindowStageCreate(windowStage: window.WindowStage) {
const client = FinAppClient.getInstance()
await client?.initContext(this.context, windowStage, this.launchWant.parameters)
}
async onWindowStageDestroy() {}
onForeground() {}
onBackground() {}
}
3.4 SDK初始化顺序
有个需要注意的就是,扩展SDK必须在核心SDK之前初始化,不能反过来。
ts
import { FinAppletShare } from '@finclip/share-sdk';
import { FinAppletContact } from '@finclip/contact-sdk';
import { FinAppletBluetooth } from '@finclip/bluetooth-sdk';
import { FinAppClient, IFinAppConfig } from '@finclip/sdk';
// 第一步:初始化扩展SDK(顺序不能错)
FinAppletShare.init('wxAppId', 'scheme')
FinAppletContact.init()
FinAppletBluetooth.init()
// 第二步:初始化核心SDK
const finAppConfig: IFinAppConfig.IFinAppConfig = {
finStoreConfigs: [{
apiServer: 'apiServer',
sdkKey: 'sdkKey',
sdkSecret: 'sdkSecret',
apmServer: 'apmServer'
}]
}
const startMode: IFinAppStartMode = {
startMode: EAppletStartMode.Ability,
uiContext: this.getUIContext()
}
FinAppClient.init(
finAppConfig,
this.context,
'AppletAbility',
startMode
)
扩展SDK包括分享、通讯录、蓝牙、日历、剪贴板、相册等模块,按需引入即可。但只要用了扩展SDK,就必须保证版本号与核心SDK一致,且初始化顺序在核心SDK之前。

3.5 启动小程序
初始化完成后,通过startApplet方法启动小程序:
ts
client.startApplet({
appId: '小程序的 appId',
apiServer: '服务器的地址'
})
携带启动参数:
ts
client.startApplet({
appId: '小程序的 appId',
apiServer: '服务器的地址',
startParams: {
path: '/pages/index/index',
query: 'floor=3&type=parking'
}
})
对于数字园区场景,停车找位和会议室预约两个小程序可以在同一个Ability下并行运行,互不干扰。用户从停车场出来直接切换到会议室预约,整个过程不需要重新登录或等待加载。
四、地图能力的特殊处理
数字园区小程序里停车找位和园区导航都会用到地图。FinClip鸿蒙SDK地图能力支持百度地图和高德地图,按需二选一即可,不需要同时集成两家。
以高德地图为例,初始化前需要先更新隐私协议状态(鸿蒙合规要求):
ts
import { FinAppletGDMap, AMapPrivacyAgreeStatus, AMapPrivacyInfoStatus, AMapPrivacyShowStatus } from '@finclip/gd-map-sdk';
FinAppletGDMap.updateLocationPrivacyShow(
AMapPrivacyShowStatus.DidShow,
AMapPrivacyInfoStatus.DidContain,
this.context
)
FinAppletGDMap.updateLocationPrivacyAgree(
AMapPrivacyAgreeStatus.DidAgree,
this.context
)
FinAppletGDMap.init('api_key')
如果项目里已经初始化过地图,不需要重新初始化,调用registerComponent()注册地图组件即可。
五、性能与上线数据
集成完成后,实测了几个关键指标:
冷启动耗时。从点击图标到首帧渲染,Ability模式下约1.8秒(测试机型:Mate 60 Pro,HarmonyOS 5.0)。这个数字和原生APP的冷启动体验基本持平,用户感知不到明显差异。
包体积影响。核心SDK增量约3.2MB,每个扩展SDK约200-500KB。如果只集成停车和会议室预约两个场景,用到的扩展SDK总增量控制在1MB以内。相比重写这两个模块的原生代码(预估8-10人/月),接入成本不到十分之一。
多小程序内存占用。同时运行3个小程序(停车+会议室+活动报名),内存占用峰值约280MB,与HarmonyOS系统小程序框架的平均水平基本一致。

六、技术边界
渲染性能上限。SDK底层基于JavaScriptCore引擎,在复杂自定义动画、长列表高频滚动等场景下,和原生代码存在差距。如果数字园区里有营销互动类的游戏小程序,用容器方案跑不起来,需要单独处理。
微信生态能力无法直接复用。微信支付、微信登录、微信分享这些API在HarmonyOS环境里没有对应的实现,业务如果重度依赖微信支付,需要在接入前确认支付通道的替代方案。
多端包管理成本。几十个小程序如果要在三个平台(微信/鸿蒙/其他)同时维护,CI/CD流程必须支持自动化打包和版本对齐。这一块如果不提前纳入工程化规划,后续维护会成为隐患。
适合:业务逻辑相对独立、不强依赖微信生态能力的工具类小程序。
不适合:重度渲染类(游戏/AR/VR)、核心商业化依赖微信生态、多小程序需要共享状态的场景。
七、实战误区
7.1 扩展SDK初始化顺序错误
现象:分享功能调不起来,点击分享按钮没有任何反应,日志里也找不到相关报错。
原因:扩展SDK在核心SDK之后才调用了初始化方法,导致分享模块没有正确注册到运行时。
解决:严格遵循"先扩展SDK、后核心SDK"的顺序,代码审核时这一点必须过审。
7.2 DevEco Studio版本不满足最低要求
现象 :集成完成后,Ability启动时报can't find module '@finclip/sdk'的错误,但依赖明明已经加了。
原因:项目使用的DevEco Studio版本低于5.0.3.300,OHPM无法正确解析SDK的依赖声明。
解决:升级DevEco Studio到5.0.3.300以上,同时确认手机系统版本在3.0.0.22以上。集成前的环境检查表要把这两项列进去。
需要的话可以在Gitee中了解一下:Gitee Finclip