鸿蒙ArkTS 与 Native 交互场景分类总结与关键实现

Native侧跨HAR/HSP模块接口调用-程序包结构-应用框架 - 华为HarmonyOS开发者

ArkTS 与 Native 交互场景分类总结与关键实现

一、场景分类总结

场景类型 调用方向 适用场景 技术特点
ArkTS → Native HAP ArkTS → 同模块 Native 高性能计算、硬件操作 使用 Node-API 直接调用
Native → Native HAP Native → HAR/HSP Native 跨模块复用底层能力 头文件导出 + SO 链接
Native → ArkTS HAR/HSP Native → 同模块 ArkTS Native 回调业务逻辑 napi_load_module 动态加载

二、关键代码流程详解

场景1:ArkTS 调用同模块 Native

调用链 ​:HAP ArkTS → HAP Native

关键流程​:

javascript 复制代码
// ArkTS 侧 (index.ets)
import napi from 'libentry.so'

Button('调用Native方法').onClick(() => {
  const result = napi.add(2, 3) // 调用Native方法
})
scss 复制代码
// Native 侧 (napi_init.cpp)
static napi_value Add(napi_env env, napi_callback_info info) {
  // 1. 解析参数
  size_t argc = 2;
  napi_value args[2];
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  
  // 2. 类型转换
  double value0, value1;
  napi_get_value_double(env, args[0], &value0);
  napi_get_value_double(env, args[1], &value1);
  
  // 3. 执行计算
  double sum = value0 + value1;
  
  // 4. 返回结果
  napi_value result;
  napi_create_double(env, sum, &result);
  return result;
}

场景2:跨模块 Native 调用

调用链 ​:HAP Native → HAR/HSP Native

关键流程​:

arduino 复制代码
// 被调用方 (HAR/HSP模块)
// napi_har.h
#pragma once
double harNativeAdd(double a, double b);

// napi_har.cpp
double harNativeAdd(double a, double b) {
  return a + b;
}
scss 复制代码
// 调用方 (HAP模块)
#include "napi_har.h" // 包含被调用方头文件

static napi_value invokeHarNative(napi_env env, napi_callback_info info) {
  // 直接调用跨模块函数
  double result = harNativeAdd(2, 3);
  
  napi_value sum;
  napi_create_double(env, result, &sum);
  return sum;
}

场景3:Native 调用 ArkTS

调用链 ​:HAR/HSP Native → 同模块 ArkTS

关键流程​:

typescript 复制代码
// ArkTS 侧 (Util.ets)
export function add(a: number, b: number): number {
  return a + b;
}
arduino 复制代码
// Native 侧 (napi_har.cpp)
napi_value harArkTSAdd(double a, double b) {
  // 1. 加载ArkTS模块
  napi_value module;
  napi_load_module_with_info(env, 
    "static_module/src/main/ets/utils/Util", // 模块路径
    "com.example.app/entry",                // 包名/模块名
    &module);
  
  // 2. 获取函数引用
  napi_value addFunc;
  napi_get_named_property(env, module, "add", &addFunc);
  
  // 3. 准备参数
  napi_value argv[2];
  napi_create_double(env, a, &argv[0]);
  napi_create_double(env, b, &argv[1]);
  
  // 4. 调用函数
  napi_value result;
  napi_call_function(env, module, addFunc, 2, argv, &result);
  return result;
}

三、CMake 配置精要

1. 被调用方 (HAR/HSP) 配置

scss 复制代码
# CMakeLists.txt (HAR/HSP模块)
add_library(native_har SHARED
    napi_har.cpp
    napi_init.cpp)

# 设置头文件搜索路径
target_include_directories(native_har PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR})
json 复制代码
// build-profile.json5 (关键导出配置)
{
  "buildOption": {
    "nativeLib": {
      "headerPath": "./src/main/cpp" // 暴露头文件
    }
  }
}

2. 调用方 (HAP) 配置

bash 复制代码
# CMakeLists.txt (HAP模块)
add_library(entry SHARED napi_init.cpp)

# 关键:链接被调用方库
target_link_libraries(entry PUBLIC
    native_har)  # 被调用方模块名::库名

# 包含被调用方头文件
target_include_directories(entry PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
    path/to/har_module/headers)
json 复制代码
// oh-package.json5 (模块依赖声明)
{
  "dependencies": {
    "native_har": "file:../native_har_module"
  }
}

四、特殊场景处理技巧

  1. 环境传递(Native 调用 ArkTS 前置条件)
java 复制代码
// HAP Native 初始化时传递环境
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
  setHarEnv(env); // 将env传递给HAR模块
  return exports;
}
EXTERN_C_END
  1. HSP/HAR 路径差异处理
arduino 复制代码
// HSP模块使用自身模块名
napi_load_module_with_info(env,
    "hsp_module/src/main/ets/MainPage",  // 实际模块名
    "com.example.app/hsp_entry",         // 包名/模块名
    &module);
  1. 解决模块加载失败
json 复制代码
// build-profile.json5 添加运行时包声明
"buildOption": {
  "arkOptions": {
    "runtimeOnly": {
      "packages": ["native_har"] // 声明依赖包
    }
  }
}

五、最佳实践建议

  1. 头文件管理​:

    • 使用 #pragma once防止重复包含
    • 为跨模块接口创建专用头文件目录
  2. 符号导出控制​:

    • 使用 __attribute__((visibility("default")))显式导出函数
    arduino 复制代码
    __attribute__((visibility("default"))) 
    double harNativeAdd(double a, double b);
  3. 错误处理增强​:

ini 复制代码
napi_status status = napi_load_module_with_info(...);
if (status != napi_ok) {
  napi_throw_error(env, "MODULE_LOAD_FAIL", "Failed to load ArkTS module");
  return nullptr;
}
  1. 性能优化​:

    • 缓存频繁调用的 ArkTS 函数引用
    • 避免在循环中频繁加载模块

关键点总结:跨模块通信的核心在于头文件导出SO链接配置环境传递。对于Native调用ArkTS,需特别注意模块路径的正确性和运行环境的传递。

相关推荐
用户4988881743717 分钟前
ArkTS 语言基础 第五节:流程控制
harmonyos
星释1 小时前
鸿蒙Flutter三方库适配指南-04.使用MacOS搭建开发环境
flutter·macos·harmonyos
ifeng09182 小时前
HarmonyOS分布式媒体播放器——跨设备音视频无缝流转
分布式·音视频·harmonyos
爱笑的眼睛113 小时前
HarmonyOS视频编解码与转码深度探索:从原理到分布式实践
华为·harmonyos
HMS Core6 小时前
【FAQ】HarmonyOS SDK 闭源开放能力 — AppGallery Kit
华为·harmonyos
王嘉俊92512 小时前
HarmonyOS 微服务与 OpenHarmony 开发:构建模块化与开源生态应用
微服务·开源·harmonyos·arkts·开发·鸿蒙
半夜偷删你代码13 小时前
鸿蒙中传感器判断移动
华为·harmonyos
星释13 小时前
鸿蒙Flutter三方库适配指南-02.Flutter相关知识基础
flutter·华为·harmonyos
爱笑的眼睛1113 小时前
HarmonyOS Canvas画布组件:高级图形绘制技术解析
华为·harmonyos
2501_9197490313 小时前
鸿蒙:将Resource类型的image转成 image.PixelMap 类型
华为·harmonyos·鸿蒙