JSI

JSI (JavaScript Interface) 是 OpenHarmony ACELite 框架中的JavaScript 接口层,它提供了 JavaScript 与 C++ 原生代码之间的高效、安全的交互机制。

JSIValue-统一表示所有值的类型

// JSI 抽象值类型
using JSIValue = struct JSIVal *;

// 创建各种类型的值
JSIValue str = JSI::CreateString("Hello");
JSIValue num = JSI::CreateNumber(42);
JSIValue obj = JSI::CreateObject();
JSIValue arr = JSI::CreateArray(5);

基础值创建

// 创建对象
JSIValue obj = JSI::CreateObject();

// 创建字符串
JSIValue str = JSI::CreateString("Hello World");

// 创建数字
JSIValue num = JSI::CreateNumber(42.5);

// 创建布尔值
JSIValue boolVal = JSI::CreateBoolean(true);

// 创建null
JSIValue nullVal = JSI::CreateNull();

// 创建undefined
JSIValue undefinedVal = JSI::CreateUndefined();

// 创建数组
JSIValue arr = JSI::CreateArray(5); // 长度为5的数组

类型检查

// 检查对象类型
JSI::ValueIsObject(value)

// 检查字符串类型
JSI::ValueIsString(value)

// 检查数字类型
JSI::ValueIsNumber(value)

// 检查布尔值类型
JSI::ValueIsBoolean(value)

// 检查null类型
JSI::ValueIsNull(value)

// 检查undefined类型
JSI::ValueIsUndefined(value)

对象操作

设置属性

JSIValue obj = JSI::CreateObject();

// 设置属性
JSI::SetNumberProperty(obj, "age", 25);
JSI::SetStringProperty(obj, "name", "张三");
JSI::SetBooleanProperty(obj, "isStudent", true);
// 嵌套对象
JSIValue address = JSI::CreateObject();
JSI::SetStringProperty(address, "city", "北京");
JSI::SetStringProperty(address, "street", "长安街");
JSI::SetNamedProperty(obj, "address", address);

// 释放对象
JSI::ReleaseValue(address);

获取属性

// 获取数字属性
double age = JSI::GetNumberProperty(obj, "age");

// 获取字符串属性
char* name = JSI::GetStringProperty(obj, "name");
// 使用字符串...
JSI::ReleaseString(name); // 必须释放

// 获取布尔属性
bool isStudent = JSI::GetBooleanProperty(obj, "isStudent");

// 获取对象属性
JSIValue address = JSI::GetNamedProperty(obj, "address");
if (!JSI::ValueIsUndefined(address)) {
    char* city = JSI::GetStringProperty(address, "city");
    // 使用...
    JSI::ReleaseString(city);
    JSI::ReleaseValue(address);
}

类型转换

// 宏定义
#define AS_JERRY_VALUE(jsiValue) (jerry_value_t)(uintptr_t) jsiValue
#define AS_JLENGTH_VALUE(jsiValue) (jerry_length_t)(uintptr_t) jsiValue
#define AS_JSI_VALUE(jValue) (JSIValue)(uintptr_t) jValue

// JSI ←→ 引擎值转换
#define AS_JSI_VALUE(jValue) (JSIValue)(uintptr_t) jValue
#define AS_JERRY_VALUE(jsiValue) (jerry_value_t)(uintptr_t) jsiValue

// 使用示例
jerry_value_t jerry_str = jerry_create_string("test");
JSIValue jsi_str = AS_JSI_VALUE(jerry_str);  // 引擎 → JSI

jerry_value_t jerry_num = AS_JERRY_VALUE(jsi_num);  // JSI → 引擎

模块调用

JS调用C++
// .h文件中声明类和函数
#ifndef OHOS_ACELITE_ROUTER_MODULE_H
#define OHOS_ACELITE_ROUTER_MODULE_H

#include "jsi.h"
#include "non_copyable.h"

namespace OHOS {
namespace ACELite {
/**
 * @brief: The module of router
 */
class RouterModule final : public MemoryHeap {
public:
    ACE_DISALLOW_COPY_AND_MOVE(RouterModule);
    RouterModule() {}
    ~RouterModule() {}
    static JSIValue Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
};

void InitRouterModule(JSIValue exports);
} // namespace ACELite
} // namespace OHOS

#endif // OHOS_ACELITE_ROUTER_MODULE_H

.cpp

#include "router_module.h"
#include "ace_log.h"
#include "js_ability_impl.h"
#include "js_app_context.h"
#include "js_profiler.h"
#include "jsi/internal/jsi_internal.h"

namespace OHOS {
namespace ACELite {
void InitRouterModule(JSIValue exports)
{
    // SetModuleAPI将RouterModule::Replace函数指向replace
    JSI::SetModuleAPI(exports, "replace", RouterModule::Replace);
}

JSIValue RouterModule::Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
{
    // 参数判断
    if (argsNum != 1 || args == nullptr) {
        HILOG_ERROR(HILOG_MODULE_ACE, "Replace args invalid, args num(%{public}d).", argsNum);
        return AS_JSI_VALUE(jerry_create_error(JERRY_ERROR_TYPE,
            reinterpret_cast<const jerry_char_t *>("params should only be one object.")));
    }
    // 获取第一个参数对象
    jerry_value_t object = AS_JERRY_VALUE(args[0]);
    // 获取应用上下文
    JsAppContext* appContext = JsAppContext::GetInstance();
    const JSAbilityImpl* topJsAbilityImpl = appContext->GetTopJSAbilityImpl();
    if (topJsAbilityImpl == nullptr) {
        HILOG_ERROR(HILOG_MODULE_ACE, "topJsAbilityImpl is null.");
        return AS_JSI_VALUE(UNDEFINED);
    }
    // 获取路由实例
    Router* router = const_cast<Router *>(topJsAbilityImpl->GetRouter());
    if (router == nullptr) {
        HILOG_ERROR(HILOG_MODULE_ACE, "router is null.");
        return AS_JSI_VALUE(UNDEFINED);
    }
    // 调用 router 的 Replace 方法执行实际的路由跳转
    jerry_value_t replaceResult = router->Replace(object);
    return AS_JSI_VALUE(replaceResult);
}
} // namespace ACELite
} // namespace OHOS

最后在ohos_module_config.h文件中注册模块

js调用

// 页面跳转. router.replace(uri: 'About', params: (id: '1')))
router.replace({
    url: 'pages/About/index',
    params: {
    id: '1',
    name: 'test'
    }
});
C++调用JS函数

GetNamedProperty提取JS对象属性,调用JS函数CallFunction

// 测试 testStandardCallback 函数 - 标准成功/失败回调
console.log('Testing testStandardCallback...');
testStandardCallback(
    success: function() {
    console.log('Success callback called! Operation completed successfully.');
    },
    fail: function() {
    console.log('Fail callback called! Operation failed.');
    },
    complete: function() {
    console.log('Complete callback called! Operation finished (success or fail).');
    }
});
JSIValue SampleModule::TestStandardCallback(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
    JSIValue undefValue = JSI::CreateUndefined();
    if ((args == nullptr) || (argsNum == 0) || JSI::ValueIsUndefined(args[0])) {
        return undefValue;
    }
    // 获取成功失败函数
    JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS);
    JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
    JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);
    // 调用函数
    JSI::CallFunction(success, thisVal, nullptr, 0);
    JSI::CallFunction(complete, thisVal, nullptr, 0);
    JSI::ReleaseValueList(success, fail, complete);
    return undefValue;
}
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐