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.jsascf-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.customResourceLoadersFlexUIEngineContext.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 报错找不到依赖。

解决

  1. 确认 HAR 文件路径正确:entry/libs/flexui_engine.har
  2. 确认 oh-package.json5file: 路径相对于 entry/ 目录
  3. 删除 oh_modulesoh-package-lock.json5 后重新 ohpm install

rawfile 资源找不到

现象:引擎初始化报 jsfwk.js not found

解决

  1. 确认文件在 entry/src/main/resources/rawfile/ 目录下
  2. 确认 coreJSAssetsPath 参数与 rawfile 中文件名一致
  3. 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'