HarmonyOS 鸿蒙Next C++子线程调用ArkTs业务层接口方法
HarmonyOS 鸿蒙Next C++子线程调用ArkTs业务层接口方法
我们在native(C++)层创建了子线程,需要在子线程中回调数据到ArkTs业务层
但是napi_env是线程相关的,怎样才能在子线程中获取napi_env实例,如Java有JVM可以获取到。或者有其他最佳方式达到这个目的。
在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鸿蒙系统中,Next C++子线程调用ArkTs(ArkUI TypeScript)业务层接口方法时,需要特别注意线程安全性和跨语言调用的规范。由于ArkTs通常运行在UI线程(主线程)上,而C++子线程直接调用UI层接口可能会导致线程冲突或界面不稳定。
为实现跨线程调用,可以采用消息传递机制。C++子线程可以通过系统提供的消息队列或其他异步通信手段,将需要调用的业务层接口方法和参数封装成消息,发送到UI线程的消息队列中。UI线程在接收到消息后,再调用相应的ArkTs接口方法。
具体实现时,可查阅HarmonyOS官方文档,了解消息队列的API使用方法,以及如何在C++和ArkTs之间进行数据传递。同时,要确保消息传递过程中的数据完整性和安全性,避免数据丢失或篡改。
此外,还需注意资源管理和内存泄漏问题。在跨线程调用中,应合理管理资源分配和释放,避免资源耗尽或内存泄漏导致系统崩溃。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html