HarmonyOS 集成指南
将 FlexUI SDK(HAR 包)集成到 HarmonyOS 应用中的完整步骤。
参考项目:
ascf-agent/entry— 完整的 FlexUI + Agent Runtime 集成示例。
1. 环境要求
| 工具 | 版本要求 |
|---|---|
| DevEco Studio | 5.0+ (API 12+) |
| hdc | 随 DevEco Studio 安装 |
| ohpm | 随 DevEco Studio 安装 |
| hvigorw | 随 DevEco Studio 安装 |
2. 引入 HAR 包
2.1 打包 HAR
在 FlexUI 项目根目录执行:
# Debug 构建
./build.sh pkg
# Release 构建
./build.sh pkg --release
产物位于 build/pkg-<date>/ohos/:
| 文件 | 说明 |
|---|---|
flexui_engine.har |
原生渲染引擎(C++ DOM + JS 驱动 + 平台连接器) |
agent_runtime.har |
Agent 运行时库(LLM 对话、工具调用、卡片渲染) |
as_apis.har |
ASCF 小程序 API 实现层 |
2.2 复制 HAR 到项目
将 HAR 文件复制到你的 HarmonyOS 项目的 entry/libs/ 目录:
cp build/pkg-*/ohos/*.har <your-project>/entry/libs/
2.3 配置依赖
在 entry/oh-package.json5 中添加依赖:
{
"dependencies": {
"flexui_engine": "file:./libs/flexui_engine.har",
"agent_runtime": "file:./libs/agent_runtime.har",
"as_apis": "file:./libs/as_apis.har"
}
}
注意:
agent_runtime依赖 Compose 相关库。如果编译报错缺少 Compose 依赖,请确保oh-package.json5中包含@ohos/aki等相关库。
3. 初始化引擎
3.1 EntryAbility 中初始化 FlexUIEngine
参考 ascf-agent/entry/src/main/ets/entryability/EntryAbility.ets:
import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit'
import { window } from '@kit.ArkUI'
import { FlexUIEngine, FlexUINativeModuleCreator } from 'flexui_engine'
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
const mainWindow = windowStage.getMainWindowSync()
// 可选:注册自定义 Native Module
const engineModules = new Map<string, FlexUINativeModuleCreator>()
FlexUIEngine.ensureInit({
context: this.context,
mainWindow: mainWindow,
enableLog: true,
coreJSAssetsPath: 'jsfwk.js', // rawfile 中的 JS 引擎文件
modules: engineModules,
debugMode: true, // debug 构建时启用 CDP 调试
debugServerHost: 'localhost:38989',
})
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
console.error('Failed to load content: ' + JSON.stringify(err))
}
})
}
onDestroy(): void {
FlexUIEngine.instance?.destroy()
}
}
关键参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
context |
Context |
应用上下文 |
mainWindow |
window.Window |
主窗口实例 |
coreJSAssetsPath |
string |
rawfile 中 JS 引擎 bundle 的路径 |
enableLog |
boolean |
是否启用引擎日志 |
debugMode |
boolean |
是否启用 CDP 调试(仅 debug 构建生效) |
debugServerHost |
string |
CDP debug server 地址 |
modules |
Map<string, FlexUINativeModuleCreator> |
自定义 Native Module 注册表 |
3.2 rawfile 资源
将 JS bundle 文件(如 jsfwk.js、ascf-ai-demo/ 目录)放入 entry/src/main/resources/rawfile/。
4. 使用 Agent Runtime
4.1 创建 AgentRuntime 实例
参考 ascf-agent/entry/src/main/ets/pages/Index.ets:
import { AgentRuntime } from 'agent_runtime'
const runtime = new AgentRuntime({
baseUrl: 'https://api.deepseek.com/v1', // LLM API 地址
apiKey: 'your-api-key', // LLM API Key
model: 'deepseek-chat', // 模型名称
baseBundlePath: 'ascf-ai-demo', // rawfile bundle 路径
maxIterations: 10, // Agent 最大循环次数
})
4.2 初始化 Agent
import { Context } from '@kit.AbilityKit'
async aboutToAppear(): Promise<void> {
const ctx = getContext(this) as Context
this.runtime.setContext(ctx)
await this.runtime.initialize()
}
4.3 集成 AgentChatView
import { AgentChatView } from 'agent_runtime'
build() {
Column() {
AgentChatView({
runtime: this.runtime,
startupMessage: '你好,请帮我推荐饮品',
})
.layoutWeight(1)
}
.width('100%')
.height('100%')
}
4.4 注册 AscfAIModule(JS ↔ Native 桥接)
Agent 的 JS bundle 通过 AscfAIModule Native Module 与原生层通信。需要在引擎就绪后注册:
import { AscfAIModule } from 'agent_runtime'
import {
FlexUIEngine,
HippyEngineContext,
HippyNativeModuleBase,
} from 'flexui_engine'
import { AscfAIModuleModule } from '../module/AscfAIModuleModule'
function registerAscfAIModule(runtime: AgentRuntime): void {
const ascfModule: AscfAIModule | null = runtime.getAscfAIModule()
if (ascfModule === null) { return }
const engine = FlexUIEngine.instance
if (engine === null) { return }
engine.onReady(() => {
const hippyEngine = engine.hippyEngine
if (hippyEngine === null) { return }
const engineCtx = hippyEngine.getHippyEngineContext()
if (engineCtx === null) { return }
// 注册 Native Module
const moduleManager = engineCtx.getModuleManager()
if (moduleManager !== null) {
const modules = new Map<string, (ctx: HippyEngineContext) => HippyNativeModuleBase>()
modules.set('AscfAIModule', AscfAIModuleModule.createCreator(ascfModule))
moduleManager.addModules(modules)
}
// 设置 callJS 桥接
const bridgeManager = engineCtx.getBridgeManager()
if (bridgeManager !== null) {
const callJS = (method: string, args: Object[]): void => {
const params: Map<string, Object> = new Map()
params.set('args', args)
bridgeManager.callJavaScriptModule('__ascfCallbacks', method, params)
}
ascfModule.setCallJSBridge(callJS, () => '[]', async (uri) => {
return new Promise<void>((resolve, reject) => {
bridgeManager.runScriptFromUri(uri, false, '', (result, msg) => {
result === 0 ? resolve() : reject(new Error(msg))
})
})
})
// 设置 follow-up 消息回调
ascfModule.setOnFollowUpMessage((message: string) => {
console.info('[AscfAIModule] follow-up message: ' + message)
})
}
})
}
注意:
AscfAIModuleModule是 Agent Runtime 内部实现的 Native Module 包装类,不在 HAR 包中公开导出。SDK 使用者需从ascf-agent/agent-runtime/src/main/ets/module/AscfAIModuleModule.ets复制该文件到自己的项目中,或根据自己的需求重新实现。其核心作用是将AscfAIModule实例封装为 Hippy 引擎可识别的HippyNativeModuleBase子类。
URL 加载规范:
runScriptFromUri/loadCard/FlexView.url接受三类 URL:
- 显式 scheme(优先级最高):
asset:/xxx.js(rawfile)、file:///xxx.js(本地文件)、http(s)://...(远程)、自定义 scheme(需先在FlexUIEngineConfig.customResourceLoaders或FlexUIEngineContext.registerResourceLoader()注册,scheme 须符合 RFC 3986[A-Za-z][A-Za-z0-9+.-]*)- 无 scheme 且以
/开头:默认按本地文件(file://前缀)处理- 无 scheme 其他(相对路径):默认按 rawfile(
asset:/前缀)处理
5. API 概览
flexui_engine
| 类/接口 | 说明 |
|---|---|
FlexUIEngine |
引擎单例,ensureInit() 初始化,destroy() 销毁 |
HippyEngineContext |
Hippy 引擎上下文 |
HippyNativeModuleBase |
自定义 Native Module 基类 |
FlexUINativeModuleCreator |
Native Module 创建器类型 |
agent_runtime
| 类/接口 | 说明 |
|---|---|
AgentRuntime |
Agent 运行时主入口,管理 LLM 对话、工具调用、卡片渲染 |
AgentChatView |
开箱即用的 Agent 聊天 UI 组件 |
LlmClient |
OpenAI 兼容的 LLM 客户端(SSE 流式响应) |
ToolRegistry |
工具注册表,管理可用工具 |
ToolExecutor |
工具执行器 |
CardRegistry / CardRenderer |
卡片注册与渲染 |
FlexCardView |
FlexView 卡片渲染组件 |
AscfAIModule |
JS ↔ Native 桥接模块 |
SkillPackageInstaller |
Skill 包安装器 |
6. 常见问题
HAR 依赖解析失败
现象:ohpm install 报错找不到依赖。
解决:
- 确认 HAR 文件路径正确:
entry/libs/flexui_engine.har - 确认
oh-package.json5中file:路径相对于entry/目录 - 删除
oh_modules和oh-package-lock.json5后重新ohpm install
rawfile 资源找不到
现象:引擎初始化报 jsfwk.js not found。
解决:
- 确认文件在
entry/src/main/resources/rawfile/目录下 - 确认
coreJSAssetsPath参数与 rawfile 中文件名一致 - rebuild 项目(hvigorw clean + assembleHap)
编译错误 10605038 (arkts-no-untyped-obj-literals)
现象:ArkTS 编译报对象字面量缺少类型。
解决:确保所有对象字面量都有显式类型标注。参考 HarmonyOS ArkTS 迁移指南。
调试日志
# 查看 Agent + Engine 日志
./build.sh logs
# 或手动
hdc shell "hilog -x" | grep -E 'AgentRuntime|FlexUIEngine|AscfAIModule'