HarmonyOS Napi创建ArkTS runtime调用ArkTS系统模块异步方法,then中的内容不会被调用

HarmonyOS
3天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
put_get

如果要在C子线程调用ArkTs方法,并且不想返回主线程。目前只能在C子线程创建Ark runtime来调用ArkTs方法。这种方式事件队列由用户控制执行(因为Ark runtime也是用户创建的)。

调用异步方法时,需要结合napi_run_event_loop和napi_stop_event_loop来开始和关闭事件循环,达到执行promise.then中的方法的目的。

第一步,ArkTs中的方法需要使用return new Promise()包装一下

// Index.ets
export function getSSID() {
  console.log("getSSID");
  return new Promise<void>((resolve) => {
    wifiManager.getLinkedInfo()
      .then((linkedInfo) => {
        console.log(`linkedInfo.ssid ${linkedInfo.ssid}`);
        resolve();
      }).catch((error: BusinessError) => {
      console.error(error.message);
    });
  })
}
/ napi_init.cpp
static void* create_and_call_subthread(void *arg) {
  napi_env env;
  napi_status ret = napi_create_ark_runtime(&env);
  if (ret != napi_ok) {
    return nullptr;
  }
  napi_value ssidModule;

  ret = napi_load_module_with_info(env, "ets/pages/Index", "com.example.promisedemo/entry", &ssidModule);
  if (ret != napi_ok) {
    return nullptr;
  }

  napi_value getSSID = nullptr;
  napi_get_named_property(env, ssidModule, "getSSID", &getSSID);

  napi_value promise = nullptr;
  napi_call_function(env, ssidModule, getSSID, 0, nullptr, &promise);

  napi_value theFunc = nullptr;
  ret = napi_get_named_property(env, promise, "then", &theFunc);
  if (ret != napi_ok) {
    return nullptr;
  }

  napi_value resolvedCallback = nullptr;
  napi_value rejectedCallback = nullptr;
  napi_create_function(env, "resolvedCallback", NAPI_AUTO_LENGTH, ResolvedCallback, nullptr, &resolvedCallback);
  napi_create_function(env, "rejectedCallback", NAPI_AUTO_LENGTH, RejectedCallback, nullptr, &rejectedCallback);
  napi_value argv[2] = {resolvedCallback, rejectedCallback};
  ret = napi_call_function(env, promise, theFunc, 2, argv, nullptr);

  napi_run_event_loop(env, napi_event_mode_default);  // 开启事件循环,开启后才会执行事件队列中的then方法。

  // napi_destroy_ark_runtime(&env);
  return nullptr;
}

static napi_value RunEventLoop(napi_env env, napi_callback_info info) {
  pthread_t tid;
  size_t argc = 1;
  napi_value argv[1] = {nullptr};
  napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);

  bool flag = false;
  napi_get_value_bool(env, argv[0], &flag);
  // 创建异步线程
  pthread_create(&tid, nullptr, create_and_call_subthread, &flag);
  pthread_join(tid, nullptr);

  return nullptr;
}

参考:https://gitee.com/openharmony/docs/blob/7d22268ac15f7bcd9116782b610e0a491e833f5c/zh-cn/application-dev/napi/use-napi-event-loop.md

如果是子线程可以回到主线程的场景,则可以使用线程安全函数的做法,在ArkTs主线程 -> C主线程 ->C创建线程安全函数执行异步任务 ->C++子线程调用ArkTs方法->通过回调在主线程获取数据参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/use-napi-thread-safety-V5

分享
微博
QQ
微信
回复
3天前
相关问题
HarmonyOS NAPI调用ArkTS静态方法
594浏览 • 1回复 待解决
HarmonyOS NAPI调用HAR模块失败
530浏览 • 1回复 待解决
C++调用ArkTS 定义方法
2040浏览 • 1回复 待解决
在Native侧调用ArkTS全局普通方法
921浏览 • 1回复 待解决
ArkTs异步方法如何转变成同步方法
2353浏览 • 0回复 待解决
HarmonyOS Image组件能调用异步方法吗?
291浏览 • 1回复 待解决
ArkTS import导入napi模块结果错误
2292浏览 • 0回复 待解决
ArkTS调用C++类成员函数
1314浏览 • 1回复 待解决