当前位置:   article > 正文

鸿蒙HarmonyOS应用开发之使用扩展的Node-API接口在异步线程中运行和停止事件循环

鸿蒙HarmonyOS应用开发之使用扩展的Node-API接口在异步线程中运行和停止事件循环

场景介绍

开发者在自己创建的ArkTS运行环境中调用异步的ArkTS接口时,可以通过使用Node-API中的扩展接口napi_run_event_loop和napi_stop_event_loop来运行和停止ArkTS实例中的事件循环。

调用异步的ArkTS接口示例

调用的ArkTS接口为异步接口时,需要通过扩展接口napi_run_event_loop将异步线程中的事件循环运行起来,底层事件队列中的异步任务将被处理执行。当前Node-API扩展了两种事件循环模式来运行异步线程的事件循环,分别为napi_event_mode_nowait模式和napi_event_mode_default模式。 如果使用napi_event_mode_nowait模式运行底层事件循环,系统会尝试从底层的事件队列中取出一个任务并处理,完成之后事件循环停止,如果底层的事件队列中没有任务,事件循环会立刻停止,当前的异步线程不会被阻塞; 如果使用napi_event_mode_default模式来运行底层事件循环,系统会阻塞当前的线程,同时会一直尝试从事件队列中获取任务并执行处理这些任务。如果不想当前线程继续被阻塞,可以使用扩展接口napi_stop_event_loop将正在运行的事件循环停止。

示例代码

  • 模块注册
// hello.cpp
#include "napi/native_api.h"
#include <napi/common.h>
#include <pthread.h>

static napi_value ResolvedCallback(napi_env env, napi_callback_info info)
{
    napi_stop_event_loop(env);
    return nullptr;
}

static napi_value RejectedCallback(napi_env env, napi_callback_info info)
{
    napi_stop_event_loop(env);
    return nullptr;
}

static void *RunEventLoopFunc(void *arg)
{
    // 1. 创建ArkTS实例
    napi_env env;
    napi_status ret = napi_create_ark_runtime(&env);
    if (ret != napi_ok) {
        return nullptr;
    }

    // 2. 加载自定义的模块
    napi_value objectUtils;
    // 'com.example.myapplication' 为当前应用的bundleName
    ret = napi_load_module_with_info(env, "ets/pages/ObjectUtils", "com.example.myapplication/entry", &objectUtils);
    if (ret != napi_ok) {
        return nullptr;
    }

    // 3. 调用异步SetTimeout接口
    napi_value setTimeout = nullptr;
    napi_value promise = nullptr;

    napi_get_named_property(env, objectUtils, "SetTimeout", &setTimeout);
    napi_call_function(env, objectUtils, setTimeout, 0, nullptr, &promise);

    napi_value theFunc = nullptr;
    if (napi_get_named_property(env, promise, "then", &theFunc) != 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};
    napi_call_function(env, promise, theFunc, 2, argv, nullptr);

    auto flag = reinterpret_cast<bool *>(arg);
    if (*flag == true) {
        napi_run_event_loop(env, napi_event_mode_default);
    } else {
        // 非阻塞式的处理任务,有可能队列中还没有任务就已经返回了
        napi_run_event_loop(env, napi_event_mode_nowait);
    }
    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, RunEventLoopFunc, &flag);
    pthread_join(tid, nullptr);

    return nullptr;
}

// 注册模块接口
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "runEventLoop", nullptr, RunEventLoop, 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 nativeModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "entry",
    .nm_priv = nullptr,
    .reserved = { 0 },
};

extern "C" __attribute__((constructor)) void RegisterEntryModule()
{
    napi_module_register(&nativeModule);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 接口声明
// index.d.ts
export const runEventLoop: (isDefault: boolean) => object;
  • 1
  • 2
  • 编译配置
  1. CMakeLists.txt文件需要按照如下配置
// CMakeLists.txt
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(myapplication)

set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})

if(DEFINED PACKAGE_FIND_FILE)
    include(${PACKAGE_FIND_FILE})
endif()

include_directories(${NATIVERENDER_ROOT_PATH}
                    ${NATIVERENDER_ROOT_PATH}/include)
add_library(entry SHARED hello.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 需要在工程的build-profile.json5文件中进行以下配置
{
    "buildOption" : {
        "arkOptions" : {
            "runtimeOnly" : {
                "sources": [
                    "./src/main/ets/pages/ObjectUtils.ets"
                ]
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • ArkTS代码示例
// index.ets
import testNapi from 'libentry.so'

testNapi.runEventLoop(true);
  • 1
  • 2
  • 3
  • 4

// ets/pages/ObjectUtils.ets
export function SetTimeout() : Promise<void> {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.info('set timer delay 1s');
            // attempt to stop the event loop at napi terminal
            resolve();
        }, 1000)
    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/328828
推荐阅读
相关标签
  

闽ICP备14008679号