1.从ArkTS层注册UI层的处理函数到C++层,该处理函数为UI的刷新处理函数,C++层收到该注册处理后,存储env信息与处理函数为全局变量。2.C++层建立的大量子线程,其各子线程的处理函数中业务处理完毕后,通过调用libuv接口(如uv_queue_work)抛ArkTS任务到loop中执行。3.在uv_queue_work中组装信息,返回给第一步中注册的函数来作UI刷新。具体方法可参考示例代码:1.ArkTS侧传递UI处理函数。// index.ets import { hilog } from '@kit.PerformanceAnalysisKit'; import testNapi from 'libentry.so'; ... .onClick(() => { testNapi.regArkts((result: number) => { hilog.info(0x0000, 'testTag', 'Pure regArkts %{public}d', result); this.message = 'result is' + result.toString(); }) }) // index.d.ts export const regArkts: (c: (a: number) => void) => number;2.native侧注册处理并抛ArkTS任务到loop中执行。#include "napi/native_api.h" #include "hilog/log.h" #include <thread> #include <unistd.h> #include <uv.h> #undef LOG_DOMAIN #undef LOG_TAG #define LOG_DOMAIN 0x3200 // 全局domain宏,标识业务领域 #define LOG_TAG "MY_TAG" // 全局tag宏,标识模块日志tag struct CallbackContext { napi_env env = nullptr; napi_ref callbackRef = nullptr; int retData = 0; }; void CallbackTest(CallbackContext *context) { std::thread::id this_id3 = std::this_thread::get_id(); OH_LOG_INFO(LOG_APP, "thread id3 %{public}lu.\n", pthread_self()); uv_loop_s *loop = nullptr; // 此处的env需要在注册Arkts回调时保存下来。从env中获取对应的Arkts线程的loop。 napi_get_uv_event_loop(context->env, &loop); // 创建uv_work_t用于传递私有数据,注意回调完成后需要释放内存,此处省略生成回传数据的逻辑,传回int类型1。 uv_work_t *work = new uv_work_t; context->retData = 1; work->data = (void *)context; // 调用libuv接口抛ArkTS任务到loop中执行。 uv_queue_work( loop, work, // 此回调在另一个普通线程中执行,用于处理异步任务,回调执行完后执行下面的回调。本场景下该回调不需要执行任务。 [](uv_work_t *work) {}, // 此回调会在env对应的ArkTS线程中执行。 [](uv_work_t *work, int status) { CallbackContext *context = (CallbackContext *)work->data; napi_handle_scope scope = nullptr; // 打开handle_scope用于管理napi_value的生命周期,否则会内存泄露。 napi_open_handle_scope(context->env, &scope); if (scope == nullptr) { return; } napi_value callback = nullptr; napi_get_reference_value(context->env, context->callbackRef, &callback); napi_value retArg; napi_create_int32(context->env, context->retData, &retArg); napi_value ret; napi_call_function(context->env, nullptr, callback, 1, &retArg, &ret); napi_delete_reference(context->env, context->callbackRef); // 关闭handle_scope释放napi_value。 napi_close_handle_scope(context->env, scope); std::thread::id this_id4 = std::this_thread::get_id(); OH_LOG_INFO(LOG_APP, "thread id4 %{public}lu.\n", pthread_self()); // 释放work指针。 if (work != nullptr) { delete work; } delete context; }); } static napi_value RegArkts(napi_env env, napi_callback_info info) { std::thread::id this_id1 = std::this_thread::get_id(); OH_LOG_INFO(LOG_APP, "thread id1 %{public}lu.\n", pthread_self()); size_t argc = 1; napi_value argv[1] = {0}; napi_value thisVar = nullptr; void *data = nullptr; napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); napi_valuetype valueType = napi_undefined; napi_typeof(env, argv[0], &valueType); if (valueType != napi_function) { return nullptr; } auto g_CallbackContext = new CallbackContext(); g_CallbackContext->env = env; napi_create_reference(env, argv[0], 1, &g_CallbackContext->callbackRef); std::thread testThread(CallbackTest, g_CallbackContext); testThread.detach(); std::thread::id this_id2 = std::this_thread::get_id(); OH_LOG_INFO(LOG_APP, "thread id2 %{public}lu.\n", pthread_self()); return thisVar; } EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { {"regArkts", nullptr, RegArkts, nullptr, nullptr, nullptr, napi_default, nullptr}}; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); return exports; } EXTERN_C_END ... // CMakeLists.txt 链接libuv库 target_link_libraries(entry PUBLIC libace_napi.z.so libuv.so libhilog_ndk.z.so)
1.从ArkTS层注册UI层的处理函数到C++层,该处理函数为UI的刷新处理函数,C++层收到该注册处理后,存储env信息与处理函数为全局变量。
2.C++层建立的大量子线程,其各子线程的处理函数中业务处理完毕后,通过调用libuv接口(如uv_queue_work)抛ArkTS任务到loop中执行。
3.在uv_queue_work中组装信息,返回给第一步中注册的函数来作UI刷新。
具体方法可参考示例代码:
1.ArkTS侧传递UI处理函数。
2.native侧注册处理并抛ArkTS任务到loop中执行。