在单独线程中调用js函数?

想在单独线程中调用JS的函数,需要在单独线程中通过napi\_create\_environment创建napi\_env,但是HarmonyOS的NDK中没有找到对应的函数。

阅读 685
1 个回答

解决方案:

HarmonyOS的NDK中没有

napi\_create\_environment,node.js官网上也没有,node.js官网:https://nodejs.cn/api/n-api.html\#node-api

如果是要在子线程调用js函数,可以使用napi_create_threadsafe_function(),创建一个线程安全函数,参考代码:
//.cpp
#include "napi/native_api.h"
#include <hilog/log.h>
#include <thread>

  // 指向napi_value js_cb
  napi_ref cbObj = nullptr;
// 线程安全函数
napi_threadsafe_function tsfn;
// Native侧Value值
static int cValue;

// 子线程运行函数
static void CallJs(napi_env env, napi_value js_cb, void *context, void *data)
{
  uv_loop_s *loop = nullptr;
  napi_get_uv_event_loop(env, &loop);


  // 获取引用值
  napi_get_reference_value(env, cbObj, &js_cb);

  // 创建一个ArkTS number作为ArkTS function的入参。
  napi_value argv;
  napi_create_int32(env, cValue, &argv);

  napi_value result = nullptr;
  napi_call_function(env, nullptr, js_cb, 1, &argv, &result);

  napi_get_value_int32(env, result, &cValue);
}_x000D_
/******/_x000D_
// Native 主线程
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([]() {
  // 可获取线程ID
  std::thread::id this_id = std::this_thread::get_id();
  napi_acquire_threadsafe_function(tsfn);
  napi_call_threadsafe_function(tsfn, NULL, napi_tsfn_blocking);
});
  t.detach();

  return NULL;
  static napi_value SetValue(napi_env env, napi_callback_info info) {
  // 从ArkTS侧获取的参数的数量
  size_t argc = 1;
  napi_value jsValue;

  // 获取ArkTS参数
  napi_get_cb_info(env, info, &argc, &jsValue, nullptr, nullptr);
  napi_get_value_int32(env, jsValue, &cValue);

  return NULL;
}

  static napi_value GetValue(napi_env env, napi_callback_info info) {
  napi_value jsValue;
  napi_create_int32(env, cValue, &jsValue);
  return jsValue;
}


  EXTERN_C_START
  static napi_value Init(napi_env env, napi_value exports)
  {
    napi_property_descriptor desc[] = {
    {"threadsTest", nullptr, ThreadsTest, nullptr, nullptr, nullptr, napi_default, nullptr},
  {"setValue", nullptr, SetValue, nullptr, nullptr, nullptr, napi_default, nullptr},
  { "getValue", nullptr, GetValue, nullptr, nullptr, nullptr, napi_default, nullptr }
  };
  napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  return exports;
}
EXTERN_C_END

static napi_module demoModule = {
  .nm_version = 1,
  .nm_flags = 0,
  .nm_filename = nullptr,
  .nm_register_func = Init,
  .nm_modname = "entry",
  .nm_priv = ((void*)0),
  .reserved = { 0 },
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{
  napi_module_register(&demoModule);
}
//.d.ts
export const threadsTest: (func: object) => number;
export const setValue: (value: number) => number;
export const getValue: () => number;_
//.ets
import entry from 'libentry.so';
import hilog from '@ohos.hilog';

@Entry
@Component
struct Index {
  @State value: number = 20;

  build() {
    Row() {
      Column() {
        Text("value: " + this.value.toString())

        Button("setValue To Native")
          .onClick(() => {
            entry.setValue(this.value)
          }).margin(10)

        Button("跨线程调用JS函数")
          .onClick(() => {
            entry.threadsTest((value:number) => {
              value += 10
              hilog.info(0x0000, 'testTag', 'js callback value = ' + value);
              return value
            })
          }).margin(10)

        Button("getValue From Native")
          .onClick(() => {
            this.value = entry.getValue()
          }).margin(10)
      }
      .width('100%')
    }
    .height('100%')
  }
}

可参考jsvm相关接口,创建js运行环境:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/\_j\_s\_v\_m-0000001880309801

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进