HarmonyOS鸿蒙Next中callback获取napi_env问题
HarmonyOS鸿蒙Next中callback获取napi_env问题 异步算子初始化后,通过Callback返回并通知js层,但是Callback没有napi_env无法,想咨询是否能全局持有napi_env或者是否有其他更优解决方案,代码如下:
// 算子初始化
_livenessChecker.Initialize({hunterModelPath, augustModelPath, alignModelPath, headPoseModelPath, eyeStateModelPath, pageantModelPath, livenessModelPath, colorModelPath, LivenessCallback, this});
// Callback
void LivenessCallback(CallbackEvent event, CallbackData callbackData, CallbackUserData callbackUserData) {
// 希望能在这里使用 napi 相关接口,但是无法获取 nap_env
}
更多关于HarmonyOS鸿蒙Next中callback获取napi_env问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
可以在注册JS回调时保存env。在callback中从env中获取对应的JS线程的loop,再调用libuv接口抛JS任务到loop中执行。
struct CallbackContext {
napi_env env = nullptr;
napi_ref callbackRef = nullptr;
int retData = 0;
};
static void callbackTest(CallbackContext * context) {
std::thread::id this_id = std::this_thread::get_id();
OH_LOG_INFO(LOG_APP, "thread id1 %d.\n", this_id);
uv_loop_s * loop = nullptr;
// 此处的env需要在注册JS回调时保存下来。从env中获取对应的JS线程的loop。
napi_get_uv_event_loop(context-> env, &loop);
uv_work_t * work = new uv_work_t;
context-> retData = 1;
work-> data = (void *)context;
// 调用libuv接口抛JS任务到loop中执行。
uv_queue_work(
loop, work,
[](uv_work_t * work) {},
[](uv_work_t * work, int status) {
CallbackContext *context = (CallbackContext *)work-> data;
napi_handle_scope scope = nullptr;
// 打开handle scope用于管理napi_value的生命周期,否则会内存泄露。
napi_open_handle_scope(context-> env, &scope);
if (scope == nullptr) {
return;
}
napi_value callback = nullptr;
napi_get_reference_value(context-> env, context-> callbackRef, &callback);
napi_value retArg;
napi_create_int32(context-> env, context-> retData, &retArg);
napi_value ret;
napi_call_function(context-> env, nullptr, callback, 1, &retArg, &ret);
napi_delete_reference(context-> env, context-> callbackRef);
// 关闭handle scope释放napi_value。
napi_close_handle_scope(context-> env, scope);
std::thread::id this_id = std::this_thread::get_id();
OH_LOG_INFO(LOG_APP, "thread id2 %d.\n", this_id);
// 释放work指针。
if (work != nullptr) {
delete work;
}
delete context;
});
}
static napi_value JSTest(napi_env env, napi_callback_info info) {
std::thread::id this_id = std::this_thread::get_id();
OH_LOG_INFO(LOG_APP, "thread id0 %d.\n", this_id);
size_t argc = 1;
napi_value argv[1] = {0};
napi_value thisVar = nullptr;
void * data = nullptr;
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
napi_valuetype valueType = napi_undefined;
napi_typeof(env, argv[0], &valueType);
if (valueType != napi_function) {
return nullptr;
}
auto asyncContext = new CallbackContext();
asyncContext-> env = env;
napi_create_reference(env, argv[0], 1, &asyncContext-> callbackRef);
std::thread testThread(callbackTest, asyncContext);
testThread.detach();
std::thread::id this_id2 = std::this_thread::get_id();
OH_LOG_INFO(LOG_APP, "thread id3 %d.\n", this_id2);
return nullptr;
}
更多关于HarmonyOS鸿蒙Next中callback获取napi_env问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,napi_env 是 Node-API 的核心环境对象,用于管理 JavaScript 和 C/C++ 之间的交互。在回调函数中获取 napi_env 时,通常需要通过 napi_get_cb_info 函数来获取当前执行环境的上下文信息。napi_get_cb_info 是 Node-API 提供的一个函数,用于从回调函数中提取 napi_env、this 对象、参数等信息。
在鸿蒙Next中,napi_env 的管理和生命周期与标准的 Node-API 一致。回调函数在执行时,napi_env 会由鸿蒙Next的运行时自动传递给回调函数。开发者可以通过 napi_get_cb_info 在回调函数中获取 napi_env,并使用它来进行后续的 JavaScript 对象操作。
需要注意的是,napi_env 在多线程环境中是线程本地的,每个线程都有自己的 napi_env 实例。因此,在回调函数中获取的 napi_env 只能在当前线程中使用,不能跨线程共享。
在鸿蒙Next中,napi_env 的使用与其他平台的 Node-API 实现保持一致,开发者可以参考 Node-API 的官方文档来了解如何使用 napi_env 进行 JavaScript 和 C/C++ 之间的交互。


