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!

2 回复

在鸿蒙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环境的唯一官方桥梁。

核心步骤:

  1. 在主线程或Worker线程中创建线程安全函数: 在你调用NDK函数并准备创建新线程的原始线程(持有有效napi_env的线程)中,使用napi_create_threadsafe_function。这个函数会创建一个特殊对象,它封装了回调到JavaScript的逻辑,并且是线程安全的。

  2. 将线程安全函数传递给NDK新线程: 将创建好的线程安全函数的“裸指针”(通常通过napi_get_threadsafe_function_context获取其上下文,并将该上下文作为void*参数)传递给你创建的NDK新线程。

  3. 在NDK新线程中调用: 在NDK新线程中,不要使用napi_env,而是使用napi_call_threadsafe_function来触发回调。这个函数是线程安全的,可以在任何线程调用。它会将调用请求安全地排队,最终在拥有napi_env的原始线程中执行对应的JavaScript回调函数。

  4. 清理: 当线程安全函数不再需要时,必须在原始线程(拥有napi_env的线程)中使用napi_release_threadsafe_function来释放它。

关键点总结:

  • napi_env 绝不能跨线程直接使用或传递。
  • 所有需要从非创建线程与JavaScript交互的操作,都必须通过线程安全函数(Thread-safe Function) 机制来完成。
  • napi_create_threadsafe_functionnapi_release_threadsafe_function 必须在拥有napi_env的原始线程中调用。
  • napi_call_threadsafe_function 可以在任何线程安全地调用。

你的架构应该是:JS线程 (napi_env) -> 创建 Threadsafe Function -> 传递上下文给NDK线程 -> NDK线程调用 napi_call_threadsafe_function

回到顶部