HarmonyOS鸿蒙Next中调用napi_create_threadsafe_function创建的js callback安全函数,传进CallJs函数的js_cb为0
HarmonyOS鸿蒙Next中调用napi_create_threadsafe_function创建的js callback安全函数,传进CallJs函数的js_cb为0 测试环境是windows的phone模拟器,使用SDK 5.0.3(15)
先使用napi_create_threadsafe_function创建了封装arkts函数的安全函数,得到tsfn。
然后在asyncwork的execute函数中使用tsfn调用napi_call_threadsafe_function,
但传进CallJs函数的js_cb为0x0,怀疑是被GC了。
workaround方法是,在使用napi_get_cb_info得到js的callback函数地址value后封装成napi_ref,再通过context方式送入CallJs函数,再提取ref得到js函数的value。
问题是是如何保证napi_create_threadsafe_function封装的CallJs得到的js_cb value是有效的?
是否将这个类型从value改成ref比较好。
更多关于HarmonyOS鸿蒙Next中调用napi_create_threadsafe_function创建的js callback安全函数,传进CallJs函数的js_cb为0的实战教程也可以访问 https://www.itying.com/category-93-b0.html
arkts:
testNapi.registerStringCallback((msg: string) => {
hilog.info(DOMAIN, 'napi string callback get msg %{public}s', msg);
})
native:
void CallJs(napi_env env, napi_value js_cb, void* context, void* data) {
auto msg = reinterpret_cast<std::string*>(data);
InitContextData *asyncData = reinterpret_cast<InitContextData*>(context);
// 此时js_cb传入是0x0
napi_get_reference_value(env, asyncData->callbackRef, &js_cb);
// 经过deref后js_cb恢复为真正的js函数地址
napi_value argv[1];
napi_create_string_utf8(env, msg->c_str(), NAPI_AUTO_LENGTH, &argv[0]);
napi_value undefined;
napi_get_undefined(env, &undefined);
// 不经过上述deref,直接使用传入的js_cb原始值不会成功
napi_call_function(env, undefined, js_cb, 1, argv, nullptr);
}
static napi_value RegisterStringCallback(napi_env env, napi_callback_info info) {
InitContextData *asyncData = nullptr;
napi_value jsCb = nullptr;
napi_get_cb_info(env, info, &argc, &jsCb, nullptr, reinterpret_cast<void **>(&asyncData));
// napi_value转换为napi_ref
napi_create_reference(env, jsCb, 1, &asyncData->callbackRef);
// 创建安全函数
napi_create_threadsafe_function(
env,
nullptr,
jsCb, // 一定被GC掉
resourceName,
0,
1,
asyncData,
nullptr,
asyncData,
CallJs,
&asyncData->tsfn
);
// 创建async work
napi_create_async_work(
env,
nullptr,
asyncWorkName,
[](napi_env env, void* data) {
InitContextData *asyncData = reinterpret_cast<InitContextData*>(data);
std::string msg = "Update Success";
// 调用安全的js函数
napi_call_threadsafe_function(
asyncData->tsfn,
new std::string(msg),
napi_tsfn_blocking
);
}
},
);
}
调试结果如下:
更多关于HarmonyOS鸿蒙Next中调用napi_create_threadsafe_function创建的js callback安全函数,传进CallJs函数的js_cb为0的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,如果napi_create_threadsafe_function
创建的JS回调函数在CallJs
时传入的js_cb
为0,可能是由于JS回调函数被垃圾回收(GC)机制回收。为避免此问题,建议在创建线程安全函数后,使用napi_reference_ref
增加对JS回调的引用计数,确保其在调用期间不被GC回收。调用完成后,使用napi_reference_unref
减少引用计数,避免内存泄漏。