HarmonyOS 鸿蒙Next C++自创线程如何回调到ArkTS应用中

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS 鸿蒙Next C++自创线程如何回调到ArkTS应用中

在C++自创线程中,如何通过回调,将数据回调到应用层ArkTS中。(据了解,NAPI中的env只能在本线程使用,且无法缓存,那么在C++自创线程中将无法获取env环境,也就无法回调) 在视频预览时,使用C++线程解码视频,并接结果(状态或数据)回调到应用层

2 回复

可以参考文档进行线程安全开发:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/use-napi-thread-safety-0000001774280466
只需要关注官方示例中创建线程安全函数部分的代码,创建异步任务的代码是演示如何使用线程安全函数的一个场景。
根据你的场景:可以在为回调函数创建完安全线程后,在子线程调用线程安全函数将结果返回给arkts。示例代码如下:
在Arkts侧调用安全函数,里面传递了一个回调函数:

entry.threadsTest((value:number) => {
  value += 10
  this.cnt += 20
  hilog.info(0x0000, 'testTag', 'js callback value = ' + value + " , cnt = " + this.cnt);
  this.value = value;
  return value
}) 

在c++侧创建一个安全函数tsfn,并把Arkts的回调函数和CallJS绑定:

// 定义线程数据结构体
struct ThreadSafeInfo {
  int sum;
};
// 实例化结构体
struct ThreadSafeInfo threadInfo = { 2 };
// 指向napi_value js_cb
napi_ref cbObj = nullptr;
// 线程安全函数
napi_threadsafe_function tsfn;
static napi_value ThreadsTest(napi_env env, napi_callback_info info)
{
  // 从ArkTS侧获取的参数的数量
  size_t argc = 1;
  napi_value js_cb, work_name;
  // 获取ArkTS参数
  napi_get_cb_info(env, info, &argc, &js_cb, nullptr, nullptr);
  // 指向napi_value js_cb 的 napi_ref cbObj
  napi_create_reference(env, js_cb, 1, &cbObj);
  // 通过UTF8编码的C字符串数据创建work_name
  napi_create_string_utf8(env, "Work Item", NAPI_AUTO_LENGTH, &work_name);
  // 创建线程安全函数
  napi_create_threadsafe_function(env, js_cb, NULL, work_name, 0, 1, NULL, NULL, NULL, CallJs, &tsfn);
  // 其他线程中调用线程安全函数
  std::thread t([]() {
napi_acquire_threadsafe_function(tsfn);
struct ThreadSafeInfo *data = &threadInfo;
napi_call_threadsafe_function(tsfn, data, napi_tsfn_blocking);
//这里的data是回调函数的入参,从别的线程拿到的数据从这里传入,注意:跨线程数据 data 引用指向的实际地址,不能随着 other 线程结束而被销毁
});
  t.detach(); return NULL;
}
//处理回调函数的逻辑写在这里
static void CallJs(napi_env env, napi_value js_cb, void *context, void* data)
{
std::thread::id this_id = std::this_thread::get_id();
std::hash<std::thread::id> hash_fn;
OH_LOG_INFO(LOG_APP, "thread id 3 = %{public}d", static_cast<int>(hash_fn(this_id)));
// 获取引用值
napi_value js_cb2 = nullptr;
napi_get_reference_value(env, cbObj, &js_cb2);
// 创建一个ArkTS number作为ArkTS function的入参。
napi_value argv;
struct ThreadSafeInfo *arg = (struct ThreadSafeInfo *)data;
OH_LOG_INFO(LOG_APP, "x = %{public}d", arg->sum);
napi_create_int64(env, arg->sum, &argv);
napi_value result = nullptr;
napi_call_function(env, nullptr, js_cb2, 1, &argv, &result);//在这里调用Arkts侧的回调函数
napi_get_value_int32(env, result, &cValue);
} 

更多关于HarmonyOS 鸿蒙Next C++自创线程如何回调到ArkTS应用中的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙系统中,如果你想在C++自创线程中回调到ArkTS(Ark UI with TypeScript)应用,通常需要通过某种形式的跨语言通信机制。以下是实现这一功能的一种基本思路:

  1. 消息队列或事件总线:在C++和ArkTS之间建立一个消息队列或事件总线,用于传递数据和事件。C++线程可以将回调信息封装成消息,发送到消息队列中。ArkTS应用则监听该队列,并在接收到消息时执行相应的回调逻辑。

  2. Native接口调用:如果ArkTS应用提供了Native接口(例如通过JSI或JNI等方式),C++线程可以直接调用这些接口来触发ArkTS中的回调。这需要确保接口的安全性和线程同步。

  3. 全局状态管理:在某些情况下,可以通过全局状态管理(如使用全局变量或单例模式)来在C++和ArkTS之间共享状态。C++线程更新状态,ArkTS应用则监听状态的变化并执行回调。

需要注意的是,跨语言通信可能会引入复杂性和性能开销,因此在设计时需要仔细考虑通信机制的选择和实现方式。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部