php网站实例宁波做网站公司
web/
2025/10/6 14:53:51/
文章来源:
php网站实例,宁波做网站公司,网站建设 知乎,杭州关键词排名工具介绍
针对JS与C/C跨语言访问场景#xff0c;NAPI使用比较繁琐。而AKI提供了极简语法糖使用方式#xff0c;一行代码完成JS与C/C的无障碍跨语言互调#xff0c;使用方便。本示例将介绍使用AKI编写C跨线程调用JS函数场景。通过调用C全局函数#xff0c;创建子线程来调用JS函…介绍
针对JS与C/C跨语言访问场景NAPI使用比较繁琐。而AKI提供了极简语法糖使用方式一行代码完成JS与C/C的无障碍跨语言互调使用方便。本示例将介绍使用AKI编写C跨线程调用JS函数场景。通过调用C全局函数创建子线程来调用JS函数实现对变量value的加10操作为开发者使用AKI提供参考。
效果图预览 使用说明
1.点击页面“AKI跨线程调用JS函数”按钮每次点击显示数值加10。
实现思路
以下是使用AKI和NPAI的libuv实现跨线程调用JS函数的实现对比
AKI和NAPI初始化。AKI初始化使用JSBIND_ADDON注册Native插件使用AKI的JSBIND_GLOBAL注册FFI特性然后在JSBIND_GLOBAL作用域下使用AKI的JSBIND_FUNCTION绑定C全局函数AkiThreadsCallJs。
...
// 使用JSBIND_ADDON注册Native插件可从JavaScript import导入插件。注册AKI插件名:即为编译*.so名称规则与NAPI一致。
JSBIND_ADDON(aki_use_practice)
// 使用JSBIND_GLOBAL注册FFI特性。用于圈定需要绑定的全局函数作用域。
JSBIND_GLOBAL() {// 在JSBIND_GLOBAL作用域下使用JSBIND_FUNCTION绑定C全局函数后可从JavaScript直接调用。JSBIND_FUNCTION(AkiThreadsCallJs);
}
...NAPI的libuv初始化需要定义napi_property_descriptor结构体准备模块加载相关信息将Init函数与模块名等信息记录下来。
...
static napi_value Init(napi_env env, napi_value exports)
{// 第一个参数add为ArkTS侧对应方法的名称。napi_property_descriptor desc[] {{UvWorkTest, nullptr, UvWorkTest, nullptr, nullptr, nullptr, napi_default, nullptr}
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}// 准备模块加载相关信息将Init函数与本模块名等信息记录下来。
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 RegisterModule(void) { napi_module_register(demoModule); } 2.AKI和NAPI在native侧的业务函数实现。
AKI在native侧业务函数实现是在AkiThreadsCallJs中创建子线程子线程中使用aki::JSBind:: GetJSFunction获取指定JavaScript函数akiAccumulate的句柄后使用Invoke触发调用。
// 定义C函数AkiThreadsCallJs。从native主线程中创建子线程subThread调用JavaScript函数。
void AkiThreadsCallJs(int value) {// 创建子线程subThreadstd::thread subThread([]() {// 使用aki::JSBind::GetJSFunction获取指定JavaScript函数句柄后使用Invoke触发调用。这里获取JS侧定义的函数akiAccumulate。if (auto func aki::JSBind::GetJSFunction(akiAccumulate)) {// 定义一个函数对象callback该函数对象接受一个整数参数并返回void。std::functionvoid(int) callback [](int value) {};// 调用JavaScript函数InvokeT指定返回值类型。func-Invokevoid(value, callback);}});// 将子线程subThread从主线程中分离出来,独立运行。subThread.detach();return;
}NAPI的libuv在native侧业务函数实现是在native主线程中实现UvWorkTest接口。接口接收到ArkTS传入的JS回调函数后创建子线程执行函数CallbackUvWorkTest。在CallbackUvWorkTest中创建工作任务workReq通过uv_queue_work将工作任务添加到libuv队列中等待被执行。
static napi_value UvWorkTest(napi_env env, napi_callback_info info) {size_t argc 1;napi_value argv[1] {0};napi_get_cb_info(env, info, argc, argv, nullptr, nullptr);napi_valuetype valueType napi_undefined;napi_typeof(env, argv[0], valueType);if (valueType ! napi_function) {OH_LOG_ERROR(LOG_APP, UvWorkTest param is not function);return nullptr;}OH_LOG_INFO(LOG_APP, UvWorkTest current value:[%{public}d], g_cValue);for (int i 0; i g_threadNum; i) {auto asyncContext new CallbackContext();if (asyncContext nullptr) {OH_LOG_ERROR(LOG_APP, UvWorkTest new asyncContext fail!);return nullptr;}asyncContext-env env;asyncContext-retData i;OH_LOG_INFO(LOG_APP, UvWorkTest thread begin index:[%{public}d], value:[%{public}d], i, g_cValue);napi_create_reference(env, argv[0], 1, asyncContext-callbackRef);std::thread testThread(CallbackUvWorkTest, asyncContext);testThread.detach();OH_LOG_INFO(LOG_APP, UvWorkTest thread end index:[%{public}d], value:[%{public}d], i, g_cValue);}return nullptr;
}void CallbackUvWorkTest(CallbackContext *context) {if (context nullptr) {OH_LOG_ERROR(LOG_APP, UvWorkTest context is nullptr);return;}uv_loop_s *loop nullptr;napi_get_uv_event_loop(context-env, loop);// 创建工作数据结构,自定义数据结构添加在data中uv_work_t *workReq new uv_work_t;if (workReq nullptr) {if (context ! nullptr) {napi_delete_reference(context-env, context-callbackRef);delete context;OH_LOG_INFO(LOG_APP, UvWorkTest delete context);context nullptr;}OH_LOG_ERROR(LOG_APP, UvWorkTest new uv_work_t fail!);return;}workReq-data (void *)context;// 此打印位于子线程OH_LOG_INFO(LOG_APP, UvWorkTest childThread_1 [%{public}d], g_cValue);// 添加工作任务到libuv的队列中uv_queue_work(loop, workReq, WorkCallback, AfterWorkCallback);
}3.AKI和NAPI在ArkTS侧调用JS函数。
AKI在ArkTS侧使用AKI的JSBind.bindFunction绑定JavaScript全局函数akiAccumulate。使用AKI调用C全局函数AkiThreadsCallJs。
...
// 使用AKI的JSBind.bindFunction绑定JavaScript全局函数。
libaki.JSBind.bindFunction(akiAccumulate, (values: number) {// 对变量value做加10操作刷新Text组件的value值。values 10;this.value values;
});
// TODO知识点使用AKI调用C全局函数AkiThreadsCallJs并传入参数value。
libaki.AkiThreadsCallJs(this.value);
...NAPI的libuv在ArkTS侧调用C全局函数UvWorkTest。
entry.UvWorkTest((values: number) {values 10;logger.info(UvWorkTest js callback value , values.toString());this.value values;return values;
}通过以上AKI和NAPI实现跨线程调用JS的实现步骤的对比可以发现AKI在native侧相较于NAPI实现的代码量要少很多使用也更加方便。
高性能知识点
1.AKI使用方便但相比于NPAI对性能的损耗相对会多一些。对性能要求不高且更需要易用性开发的场景推荐使用AKI。
工程结构模块类型
akiusepractice // har类型
|---src\main\cpp
| |---akiusepractice.cpp // native层-native侧业务处理
| |---CMakeLists.txt // native层-AKI相关CMake配置
|---src\main\ets\view
| |---AkiView.ets // 视图层-AKI跨线程调用JS函数页面 模块依赖
本实例依赖AKI。
本实例依赖common模块来实现公共组件FunctionDescription。
为了帮助大家更深入有效的学习到鸿蒙开发知识点小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源获取完整版方式请点击→HarmonyOS教学视频https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
HarmonyOS教学视频语法ArkTS、TypeScript、ArkUI等…视频教程 鸿蒙生态应用开发白皮书V2.0PDF 获取完整版白皮书方式请点击→https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG?ua42c4946d1514235863bb82a7b2ac128 鸿蒙 (Harmony OS)开发学习手册→https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
一、入门必看
1.应用开发导读(ArkTS) 2………
二、HarmonyOS 概念→https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.系统定义 2.技术架构 3.技术特性 4.系统安全 5…
三、如何快速入门→https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.基本概念 2.构建第一个ArkTS应用 3…
四、开发基础知识→https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.应用基础知识 2.配置文件 3.应用数据管理 4.应用安全管理 5.应用隐私保护 6.三方应用调用管控机制 7.资源分类与访问 8.学习ArkTS语言
五、基于ArkTS 开发→https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.Ability开发 2.UI开发 3.公共事件与通知 4.窗口管理 5.媒体 6.安全 7.网络与链接 8.电话服务 9.数据管理 10.后台任务(Background Task)管理 11.设备管理 12.设备使用信息统计 13.DFX 14.国际化开发 15.折叠屏系列
更多了解更多鸿蒙开发的相关知识可以参考https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87969.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!