【每日学点鸿蒙知识】JSVM-API、热修复、对象唯一哈希值、监听VPN网络变化等

发布于:2025-02-10 ⋅ 阅读:(30) ⋅ 点赞:(0)

1、如何使用JSVM-API接口创建多个引擎执行JS代码并销毁?

通过CreateJsCore方法来创建一个新的JS基础运行时环境同时获得一个CoreID:

static napi_value CreateJsCore(napi_env env1, napi_callback_info info) {
  OH_LOG_INFO(LOG_APP, "JSVM CreateJsCore START");
  size_t argc = 1;
  napi_value argv[1];
  napi_get_cb_info(env1, info, &argc, argv, nullptr, nullptr);
  if (argc < 1) {
    OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore the number of params must be one");
    return nullptr;
  }
  g_napiEnvMap[ENVTAG_NUMBER] = env1;
  g_taskQueueMap[ENVTAG_NUMBER] = deque<Task *>{};
  // 将TS侧传入的回调函数与env对应存储方便后续调用
  napi_ref callFun;
  napi_create_reference(env1, argv[0], 1, &callFun);
  g_callBackMap[ENVTAG_NUMBER] = callFun;
  napi_value coreID = 0;
  {
    std::lock_guard<std::mutex> lock_guard(envMapLock);
    CreateArkJSContext();
    napi_create_uint32(env1, ENVTAG_NUMBER, &coreID);
    ENVTAG_NUMBER++;
  }
  OH_LOG_INFO(LOG_APP, "JSVM CreateJsCore END");
  return coreID;
}

通过EvalUateJS方法使用CoreID对应的运行环境来运行JS代码:

static napi_value EvalUateJS(napi_env env, napi_callback_info info) {
  OH_LOG_INFO(LOG_APP, "JSVM EvalUateJS START");
  size_t argc = 2;
  napi_value args[2] = {nullptr};
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  uint32_t envId;
  napi_status status = napi_get_value_uint32(env, args[0], &envId);
  if (status != napi_ok) {
    OH_LOG_ERROR(LOG_APP, "EvalUateJS first param should be number");
    return nullptr;
  }

  if (g_envMap.count(envId) == 0 || g_envMap[envId] == nullptr) {
    OH_LOG_ERROR(LOG_APP, "EvalUateJS env is null");
    return nullptr;
  }
  std::string dataStr = napiValueToString(env, args[1]);
  napi_value res = nullptr;
  std::lock_guard<std::mutex> lock_guard(mutexLock);
  {
    // open handle scope
    JSVM_HandleScope handlescope;
    OH_JSVM_OpenHandleScope(*g_envMap[envId], &handlescope);
    // compile js script
    JSVM_Value sourcecodevalue;
    OH_JSVM_CreateStringUtf8(*g_envMap[envId], dataStr.c_str(), dataStr.size(), &sourcecodevalue);
    JSVM_Script script;
    OH_JSVM_CompileScript(*g_envMap[envId], sourcecodevalue, nullptr, 0, true, nullptr, &script);
    // run js script
    JSVM_Value result;
    OH_JSVM_RunScript(*g_envMap[envId], script, &result);
    JSVM_ValueType type;
    OH_JSVM_Typeof(*g_envMap[envId], result, &type);
    OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
    // Execute tasks in the current env event queue
    while (!g_taskQueueMap[envId].empty()) {
      auto task = g_taskQueueMap[envId].front();
      g_taskQueueMap[envId].pop_front();
      task->Run();
      delete task;
    }

    if (type == JSVM_STRING) {
      std::string stdResult = fromOHStringValue(*g_envMap[envId], result);
      napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
    } else if (type == JSVM_BOOLEAN) {
      bool ret = false;
      std::string stdResult;
      OH_JSVM_GetValueBool(*g_envMap[envId], result, &ret);
      ret ? stdResult = "true" : stdResult = "false";
      napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
    } else if (type == JSVM_NUMBER) {
      int32_t num;
      OH_JSVM_GetValueInt32(*g_envMap[envId], result, &num);
      std::string stdResult = std::to_string(num);
      napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
    } else if (type == JSVM_OBJECT) {
      JSVM_Value objResult;
      OH_JSVM_JsonStringify(*g_envMap[envId], result, &objResult);
      std::string stdResult = fromOHStringValue(*g_envMap[envId], objResult);
      napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
    }
    OH_JSVM_CloseHandleScope(*g_envMap[envId], handlescope);
  }
  OH_LOG_INFO(LOG_APP, "JSVM EvalUateJS END");
  return res;
}

通过ReleaseJsCore方法来释放CoreID对应的运行环境:

static napi_value ReleaseJsCore(napi_env env1, napi_callback_info info) {
  OH_LOG_INFO(LOG_APP, "JSVM ReleaseJsCore START");
  size_t argc = 1;
  napi_value argv[1];
  napi_get_cb_info(env1, info, &argc, argv, nullptr, nullptr);
  if (argc < 1) {
    OH_LOG_ERROR(LOG_APP, "JSVM ReleaseJsCore the number of params must be one");
    return nullptr;
  }

  uint32_t coreEnvId;
  napi_status status = napi_get_value_uint32(env1, argv[0], &coreEnvId);
  if (status != napi_ok) {
    OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore napi_get_value_uint32 faild");
    return nullptr;
  }
  if (g_envMap.count(coreEnvId) == 0 ) {
    OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore not has env ");
    return nullptr;
  }
  if (g_envMap[coreEnvId] != nullptr) {
    std::lock_guard<std::mutex> lock_guard(envMapLock);
    OH_JSVM_CloseEnvScope(*g_envMap[coreEnvId], g_envScopeMap[coreEnvId]);
    g_envScopeMap.erase(coreEnvId);
    OH_JSVM_DestroyEnv(*g_envMap[coreEnvId]);
    g_envMap[coreEnvId] = nullptr;
    g_envMap.erase(coreEnvId);
    OH_JSVM_CloseVMScope(*g_vmMap[coreEnvId], g_vmScopeMap[coreEnvId]);
    g_vmScopeMap.erase(coreEnvId);
    OH_JSVM_DestroyVM(*g_vmMap[coreEnvId]);
    g_vmMap[coreEnvId] = nullptr;
    g_vmMap.erase(coreEnvId);
    delete [] g_callBackStructMap[coreEnvId];
    g_callBackStructMap[coreEnvId] = nullptr;
    g_callBackStructMap.erase(coreEnvId);
    napi_delete_reference(env1, g_callBackMap[coreEnvId]);
    g_callBackMap.erase(coreEnvId);
    g_taskQueueMap.erase(coreEnvId);
  }
  OH_LOG_INFO(LOG_APP, "JSVM ReleaseJsCore END");
  return nullptr;
}

2、错误码9568258,error:install releaseType not same怎么处理?

IDE升级后,装包一直提示code:9568258,error:install releaseType not same,手机格式化后还是这样。怀疑是hsp包导致的,但现在私仓上有14个hsp包,要全部重新打一次不现实,工作量太大,是否有其它解决办法?

方法一:本机上未卸载之前的hap,需要卸载设备hap重新安装。
方法二: 安装了不同SDK版本编译的hap导致,可以搜索releasetype看一下生成产物里面的对应的sdk的值,确定一下是否和当前版本一样。

3、如何对监听判断VPN类型网络?

VPN类型可使用getNetCapabilities方法获取到bearerTypes,当bearerTypes的值是4时表示使用了VPN;示例代码:

connection.getDefaultNet().then((netHandle: connection.NetHandle) => {
  connection.getNetCapabilities(netHandle).then((data: connection.NetCapabilities) => {
    const type: Number = data.bearerTypes[0];
    if (type === 4) {
      console.info('is vpn');
    }
  })
});

4、如何获取对象的唯一标识(Hash值)?

使用util.getHash接口。
如果是第一次获取,则计算Hash值并保存到对象的Hash域(返回随机的Hash值);
如果不是第一次获取,则从Hash域中获取并返回Hash值(同一对象多次返回值保持不变)。

5、是否推荐使用bm quickfix制造修复包?

参考文档文档中显示:# 快速修复补丁安装bm quickfix -a -f /data/app/有两个问题:

  1. hqf文件如何制作的文档没有找到。
  2. hqf 是不是新版本和旧版本的差分包咨询场景描述:app可以在运行过程中修复部分bug功能,是不是可以用上吗的bm quickfix命令来修复,是否有相关的参考文档?

当前不推荐手动制作HQF包,推荐使用热重载能力:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-hot-reload-0000001527628941-V5?catalogVersion=V5