鸿蒙开发5.0【JSVM创建引擎执行JS代码并销毁】

场景描述

通过JSVM,可以在应用运行期间直接执行一段动态加载的JS代码。也可以选择将一些对性能、底层系统调用有较高要求的核心功能用C/C++实现并将C++方法注册到JS侧,在JS代码中直接调用,提高应用的执行效率。

功能描述

通过createJsCore方法来创建一个新的JS基础运行时环境,并通过该方法获得一个虚拟机ID,通过evalUateJS方法使用虚拟机ID对应的运行环境来运行JS代码,在JS代码中创建promise并异步调取TS侧设定的callback函数,最后使用releaseJsCore方法来释放虚拟机ID对应的运行环境。

JSVM主要交互流程

1

接口介绍

创建所需接口:

// 初始化虚拟机
JSVM_EXTERN JSVM_Status OH_JSVM_Init(const JSVM_InitOptions* options);
​
// 创建虚拟机实例
JSVM_EXTERN JSVM_Status OH_JSVM_CreateVM(const JSVM_CreateVMOptions* options,JSVM_VM* result);
​
// 创建虚拟机作用域
JSVM_EXTERN JSVM_Status OH_JSVM_OpenVMScope(JSVM_VM vm,JSVM_VMScope* result);
​
// 创建上下文环境
JSVM_EXTERN JSVM_Status OH_JSVM_CreateEnv(JSVM_VM vm,size_t propertyCount,const JSVM_PropertyDescriptor* properties,JSVM_Env* result);
​
// 创建上下文环境作用域
JSVM_EXTERN JSVM_Status OH_JSVM_OpenEnvScope(JSVM_Env env,JSVM_EnvScope* result);

执行所需接口:

// 开启新作用域
JSVM_EXTERN JSVM_Status OH_JSVM_OpenHandleScope(JSVM_Env env,JSVM_HandleScope* result);
​
// 编译一串JS代码,并返回编译后脚本
JSVM_EXTERN JSVM_Status OH_JSVM_CompileScript(JSVM_Env env,JSVM_Value script,const uint8_t* cachedData,size_t cacheDataLength,bool eagerCompile,bool* cacheRejected,JSVM_Script* result);
​
// 执行一段JS代码并返回结果
JSVM_EXTERN JSVM_Status OH_JSVM_RunScript(JSVM_Env env,JSVM_Script script,JSVM_Value* result);
​
// 关闭传入的作用域
JSVM_EXTERN JSVM_Status OH_JSVM_CloseHandleScope(JSVM_Env env,JSVM_HandleScope scope);

关闭所需接口:

// 关闭上下文环境作用域
JSVM_EXTERN JSVM_Status OH_JSVM_CloseEnvScope(JSVM_Env env,JSVM_EnvScope scope);
​
// 销毁上下文环境
JSVM_EXTERN JSVM_Status OH_JSVM_DestroyEnv(JSVM_Env env);
​
// 关闭虚拟机作用域
JSVM_EXTERN JSVM_Status OH_JSVM_CloseVMScope(JSVM_VM vm,JSVM_VMScope scope);
​
// 销毁虚拟机实例
JSVM_EXTERN JSVM_Status OH_JSVM_DestroyVM(JSVM_VM vm);

场景代码

场景一:JSVM执行JS代码并回调C++代码

创建虚拟机所需环境,编译并执行JS代码回调C++代码,销毁之前创建的虚拟机环境。

配置

cmakelists:

target_link_libraries(entry PUBLIC libjsvm.so)

ArkTS代码:

示例中包含了提供给JSVM的JS里的consoleinfo同步方法,createPromise创建异步方法,执行assertEqual方法,onJSResultCallback异步方法回调。

  1. 调用Native的创建虚拟机及环境的接口,绑定MyCallback回调(用于JS代码里onJSResultCallback方法的回调),接收native返回的虚拟机id。
  2. 调用Native的执行JS代码的接口,传入虚拟机id和JS代码字符串,在native侧的虚拟机里编译并执行。
  3. 调用Native的销毁虚拟机及环境的接口,传入虚拟机id,指定销毁对应的虚拟机和环境。

可以同时运行多个JSVM虚拟机执行多个JS代码。

import testNapi from 'libentry.so';
​
// 用于JSVM执行的JS代码字符串
let jsCodeStr = `{
let a = "hello World";
consoleinfo(a);
let b = add(99, 1);
const mPromise = createPromise();
mPromise.then((result) => {
assertEqual(result, 0);
onJSResultCallback(result, "abc", "v");
});
a;
};`;
​
function MyCallback(a:string, b:string):string {
  console.log("TEST MyCallback run: " + a);
  b = "callback done";
  console.log("TEST MyCallback run: " + b);
  return "callback pass";
}
​
// 创建首个运行环境,并绑定TS回调
const coreId = testNapi.createJsCore(MyCallback);
// 在首个运行环境中执行JS代码
testNapi.evalUateJS(coreId, jsCodeStr);
// 释放首个运行环境
testNapi.releaseJsCore(coreId);

Native代码:

JS运行环境创建,创建让JS代码运行的虚拟机环境:

  1. 通过OH_JSVM_Init初始化虚拟机。
  2. 通过OH_JSVM_CreateVM创建虚拟机实例。
  3. 通过OH_JSVM_OpenVMScope创建虚拟机作用域。
  4. 将本地函数的回调函数放到JSVM_PropertyDescriptor集合中(用于JS调用的C++函数)。
  5. 通过OH_JSVM_CreateEnv创建上下文环境并注册JSVM_PropertyDescriptor。
  6. 通过OH_JSVM_OpenEnvScope创建上下文环境作用域。
static void CreateArkJSContext() {
  JSVM_Status status;
  JSVM_InitOptions init_options;
  memset(&init_options, 0, sizeof(init_options));
  if (aa == 0) {

    //****1****初始化JSVM
    OH_JSVM_Init(&init_options);
    aa++;
  }
  ​
  g_vmMap[ENVTAG_NUMBER] = new JSVM_VM;
  JSVM_VMScope vmScope;
  g_vmScopeMap[ENVTAG_NUMBER] = vmScope;
  JSVM_CreateVMOptions options;
  memset(&options, 0, sizeof(options));

  //****2****创建JSVM实例
  status = OH_JSVM_CreateVM(&options, g_vmMap[ENVTAG_NUMBER]);

  //****3****创建JSVM作用域
  status = OH_JSVM_OpenVMScope(*g_vmMap[ENVTAG_NUMBER], &g_vmScopeMap[ENVTAG_NUMBER]);
  ​
  g_envMap[ENVTAG_NUMBER] = new JSVM_Env;
  g_callBackStructMap[ENVTAG_NUMBER] = new JSVM_CallbackStruct[5];
  // 注册用户提供的本地函数的回调函数指针和数据,通过JSVM-API暴露给JS
  for (int i = 0; i < 5; i++) {
    g_callBackStructMap[ENVTAG_NUMBER][i].data = nullptr;
  }
  g_callBackStructMap[ENVTAG_NUMBER][0].callback = Co
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值