如何在C++代码中使用OH_JSVM_PumpMessageLoop和OH_JSVM_PerformMicrotaskCheckpoint接口启动任务队列并执行任务(结合示例代码说明)?

如题:如何在C++代码中使用OH_JSVM_PumpMessageLoop和OH_JSVM_PerformMicrotaskCheckpoint接口启动任务队列并执行任务(结合示例代码说明)?

本文参与了 【 HarmonyOS NEXT 技术问答冲榜,等你来战!】欢迎正在阅读的你也加入。

阅读 510
1 个回答

在C++代码中,首先进行JavaScript虚拟机的初始化(如果未初始化),创建JavaScript虚拟机实例并打开虚拟机作用域,注册相关方法(如consoleinfo方法用于输出信息),创建执行环境并打开相关作用域(EnvScopeHandleScope)。然后创建JSVM_Value表示要执行的JavaScript代码字符串,编译脚本并执行。接着通过循环调用OH_JSVM_PumpMessageLoopOH_JSVM_PerformMicrotaskCheckpoint接口,检查任务队列状态,如果任务启动则执行相关操作(如等待一段时间)。最后关闭并销毁环境和虚拟机,将OH_JSVM_PumpMessageLoop执行后的结果转换为布尔类型返回。示例代码如下:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <cassert>
#include <string.h>
#include "hilog/log.h"
#include "napi/native_api.h"
#include <unistd.h>

// 全局变量,保证虚拟机只初始化一次
static int aa = 0;
// 待执行的js代码
static const char *STR_TASK = R"JS(
new Promise((resolve,reject) => {
    resolve(1)
})
.then(function(obj) {
    consoleinfo("Called with instance " + obj);
}).catch(function(err) {
    consoleinfo("Called with error ");
});
)JS";

// 保证js代码中的打印信息可以正常输出
static JSVM_Value ConsoleInfo(JSVM_Env env, JSVM_CallbackInfo info) {
    size_t argc = 1;
    JSVM_Value args[1];
    char log[256] = "";
    size_t logLength;
    OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
    OH_JSVM_GetValueStringUtf8(env, args[0], log, 255, &logLength);
    log[255] = 0;
    OH_LOG_INFO(LOG_APP, "JSVM API TEST: %{public}s", log);
    return nullptr;
}

// 启动任务队列里的任务并执行
static napi_value testHandleMicrotasks(napi_env env1, napi_callback_info info) {
    JSVM_InitOptions init_options;
    memset(&init_options, 0, sizeof(init_options));
    if (aa == 0) {
        OH_JSVM_Init(&init_options);
        aa++;
    }
    // 创建JavaScript虚拟机实例,打开虚拟机作用域
    JSVM_VM vm;
    JSVM_CreateVMOptions options;
    memset(&options, 0, sizeof(options));
    OH_JSVM_CreateVM(&options, &vm);
    JSVM_VMScope vm_scope;
    OH_JSVM_OpenVMScope(vm, &vm_scope);
    // 注册consoleinfo的方法
    JSVM_CallbackStruct param[] = {
        {.data = nullptr,.callback = ConsoleInfo},
    };
    JSVM_PropertyDescriptor descriptor[] = {
        {"consoleinfo", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
    };
    JSVM_Env env;
    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
    JSVM_EnvScope envScope;
    OH_JSVM_OpenEnvScope(env, &envScope);
    JSVM_HandleScope handlescope;
    OH_JSVM_OpenHandleScope(env, &handlescope);
    JSVM_Value sourcecodevalue;
    OH_JSVM_CreateStringUtf8(env, STR_TASK, strlen(STR_TASK), &sourcecodevalue);
    JSVM_Script script;
    OH_JSVM_CompileScript(env, sourcecodevalue, nullptr, 0, true, nullptr, &script);
    JSVM_Value result;
    OH_JSVM_RunScript(env, script, &result);
    bool rst = false;
    for (int i = 0; i < 3; i++) { // 3: cycles
        // 如果消息队列中没有任务启动,则rst设置为false。
        JSVM_Status flag1 = OH_JSVM_PumpMessageLoop(vm, &rst);
        JSVM_Status flag2 = OH_JSVM_PerformMicrotaskCheckpoint(vm);
        if (rst && flag1 == JSVM_Status::JSVM_OK && flag2 == JSVM_Status::JSVM_OK) {
            sleep(3);
            break;
        }
    }
    // 关闭并销毁环境和虚拟机
    OH_JSVM_CloseHandleScope(env, handlescope);
    OH_JSVM_CloseEnvScope(env, envScope);
    OH_JSVM_DestroyEnv(env);
    OH_JSVM_CloseVMScope(vm, vm_scope);
    OH_JSVM_DestroyVM(vm);
    // 将OH_JSVM_PumpMessageLoop执行后返回的结果转换为布尔类型输出
    napi_value result11;
    napi_status status = napi_get_boolean(env1, rst, &result11);
    assert(status == napi_ok);
    return result11;
}

本文参与了 【 HarmonyOS NEXT 技术问答冲榜,等你来战!】欢迎正在阅读的你也加入。

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