You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从原生代码直接在Hermes中同步执行预编译JavaScript代码?

解决方案:原生代码同步调用Hermes执行预编译JS

可以直接通过Hermes引擎在原生代码中同步执行预编译的JavaScript代码,完全绕开React Native的异步桥接机制。下面分iOS和Android平台说明具体实现方式:

一、预编译JavaScript代码

先将你的跨平台功能写成独立JS文件(比如syncFunctions.js),再用Hermes编译器预编译为字节码:

hermesc -output syncFunctions.hbc syncFunctions.js

把生成的.hbc文件添加到项目资源:

  • iOS:拖入Xcode项目,勾选"Copy items if needed"
  • Android:放入src/main/assets目录

二、Android平台实现

  1. 确保项目已启用Hermes(android/app/build.gradle中enableHermes = true)
  2. 原生代码中初始化Hermes引擎、加载字节码并同步执行:
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.hermes.HermesExecutorFactory;
import java.io.IOException;
import java.io.InputStream;

public class SyncJsExecutor {
    private final JavaScriptContextHolder jsContext;

    public SyncJsExecutor(ReactApplicationContext reactContext) {
        HermesExecutorFactory factory = new HermesExecutorFactory(reactContext);
        jsContext = factory.createJavaScriptContext();
        
        try {
            InputStream is = reactContext.getAssets().open("syncFunctions.hbc");
            byte[] bytes = new byte[is.available()];
            is.read(bytes);
            is.close();
            jsContext.get().evaluateJavaScript(bytes, "syncFunctions.hbc");
        } catch (IOException e) {
            throw new RuntimeException("加载Hermes字节码失败", e);
        }
    }

    // 同步调用JS函数
    public String callSyncFunction(String functionName, String param) {
        String jsCode = String.format("%s('%s')", functionName, param);
        return (String) jsContext.get().evaluateJavaScript(jsCode, "callSync");
    }
}

使用时直接在原生代码中实例化调用,全程同步无异步回调。

三、iOS平台实现

  1. 确保项目已集成Hermes(Podfile中包含pod 'Hermes-engine')
  2. 原生代码中初始化Hermes并执行:

Objective-C示例

#import <HermesEngine/HermesEngine.h>

@interface SyncJSExecutor : NSObject
@property (nonatomic, strong) HermesRuntime *runtime;
@end

@implementation SyncJSExecutor

- (instancetype)init {
    self = [super init];
    if (self) {
        self.runtime = [[HermesRuntime alloc] init];
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"syncFunctions" ofType:@"hbc"];
        NSData *bytecode = [NSData dataWithContentsOfFile:filePath];
        [self.runtime evaluateJavaScript:bytecode sourceURL:[NSURL fileURLWithPath:filePath]];
    }
    return self;
}

- (NSString *)callSyncFunction:(NSString *)functionName withParam:(NSString *)param {
    NSString *jsCode = [NSString stringWithFormat:@"%@('%@')", functionName, param];
    return [self.runtime evaluateJavaScript:jsCode sourceURL:nil];
}

@end

Swift示例

import HermesEngine

class SyncJSExecutor {
    private let runtime: HermesRuntime

    init() {
        self.runtime = HermesRuntime()
        guard let filePath = Bundle.main.path(forResource: "syncFunctions", ofType: "hbc"),
              let bytecode = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
            fatalError("加载Hermes字节码失败")
        }
        _ = runtime.evaluateJavaScript(bytecode, sourceURL: URL(fileURLWithPath: filePath))
    }

    func callSyncFunction(_ functionName: String, param: String) -> String? {
        let jsCode = "\(functionName)('\(param)')"
        return runtime.evaluateJavaScript(jsCode, sourceURL: nil) as? String
    }
}

四、注意事项

  • JS代码需为纯函数,避免依赖React Native原生API(无桥接无法访问)
  • 数据传递仅支持基础类型,复杂类型需手动序列化/反序列化
  • 确保Hermes版本与React Native版本兼容
  • 不要在主线程执行耗时JS逻辑,避免阻塞UI

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:27:40