HarmonyOS鸿蒙Next中在NDK层的新线程中如何使用napi_env指针?
HarmonyOS鸿蒙Next中在NDK层的新线程中如何使用napi_env指针? 我在一个worker线程中调用一个NDK层的函数,该NDK层的函数又创建了一个NDK层的新线程,那么该NDK层的新线程中如何才能使用napi_env指针?
我尝试直接将worker线程的napi_env指针复制到NDK层的新线程中使用,会报错:
Fatal: ecma_vm cannot run in multi-thread!
在鸿蒙Next的NDK层新线程中,napi_env指针不能跨线程直接使用。每个线程需要从napi_ext_threadsafe_function获取独立的napi_env。具体通过napi_get_threadsafe_function_context获取上下文后,调用napi_open_callback_scope创建新的作用域来获得当前线程可用的napi_env。
更多关于HarmonyOS鸿蒙Next中在NDK层的新线程中如何使用napi_env指针?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next的NDK开发中,napi_env指针与创建它的线程(通常是主线程或Worker线程)是严格绑定的,不能直接跨线程使用。你遇到的错误正是因为这个原因。
正确的方法是: 在NDK层的新线程中,你需要通过napi_create_threadsafe_function来创建一个线程安全的函数(Thread-safe Function),这是连接任意NDK线程与JavaScript环境的唯一官方桥梁。
核心步骤:
-
在主线程或Worker线程中创建线程安全函数: 在你调用NDK函数并准备创建新线程的原始线程(持有有效
napi_env的线程)中,使用napi_create_threadsafe_function。这个函数会创建一个特殊对象,它封装了回调到JavaScript的逻辑,并且是线程安全的。 -
将线程安全函数传递给NDK新线程: 将创建好的线程安全函数的“裸指针”(通常通过
napi_get_threadsafe_function_context获取其上下文,并将该上下文作为void*参数)传递给你创建的NDK新线程。 -
在NDK新线程中调用: 在NDK新线程中,不要使用
napi_env,而是使用napi_call_threadsafe_function来触发回调。这个函数是线程安全的,可以在任何线程调用。它会将调用请求安全地排队,最终在拥有napi_env的原始线程中执行对应的JavaScript回调函数。 -
清理: 当线程安全函数不再需要时,必须在原始线程(拥有
napi_env的线程)中使用napi_release_threadsafe_function来释放它。
关键点总结:
napi_env绝不能跨线程直接使用或传递。- 所有需要从非创建线程与JavaScript交互的操作,都必须通过线程安全函数(Thread-safe Function) 机制来完成。
napi_create_threadsafe_function和napi_release_threadsafe_function必须在拥有napi_env的原始线程中调用。napi_call_threadsafe_function可以在任何线程安全地调用。
你的架构应该是:JS线程 (napi_env) -> 创建 Threadsafe Function -> 传递上下文给NDK线程 -> NDK线程调用 napi_call_threadsafe_function。

