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

如何从Java调用JavaScript函数?NativeScript插件向Android原生库传JS函数?

如何从Java调用JavaScript函数 & NativeScript插件中传递JS回调给Android原生库

我来帮你拆解这两个问题,分场景给你详细说明实现方案:

一、Java中调用JavaScript函数的几种常见方式

1. 普通Java应用:使用内置JS引擎(Nashorn/GraalVM)

如果是桌面或后端Java应用,JDK提供了直接执行JS代码的能力。JDK8及以前用Nashorn引擎,JDK11+推荐用GraalVM的JavaScript引擎(Nashorn已被移除)。

举个Nashorn的例子:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JavaInvokeJS {
    public static void main(String[] args) throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine nashorn = manager.getEngineByName("nashorn");
        
        // 先定义一个JS函数
        nashorn.eval("function sayHi(name) { return `Hi, ${name}!`; }");
        
        // 调用这个JS函数并获取结果
        String result = (String) nashorn.eval("sayHi('Java Dev')");
        System.out.println(result); // 输出: Hi, Java Dev!
    }
}

如果用GraalVM,需要先添加对应依赖(比如Maven),然后把引擎名称换成graal.js,核心逻辑和上面一致。

2. Android应用:通过WebView调用JS函数

如果是Android开发,用WebView加载网页后,可以通过evaluateJavascript方法调用页面中的JS函数:

WebView myWebView = findViewById(R.id.my_webview);
myWebView.getSettings().setJavaScriptEnabled(true);

// 网页加载完成后调用JS函数
myWebView.evaluateJavascript("sayHi('Android User')", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        // 注意返回值是JSON格式字符串,需要按需解析
        Log.d("JS_CALL", "返回结果: " + value);
    }
});

二、NativeScript插件中传递JS回调给Android原生库

这个场景需要做Java和JS的桥接,核心是让Android原生库的事件能触发JS层的函数。我给你一步步讲实现:

先明确前提

假设你的Android原生库有一个回调接口,比如:

// 原生库的回调接口
public interface MyNativeCallback {
    void onEventHappened(String eventData);
}

并且原生库有方法接收这个回调:

public class MyNativeLibrary {
    public void registerCallback(MyNativeCallback callback) {
        // 保存回调,当事件发生时调用callback.onEventHappened()
    }
}

步骤1:在插件Java层写桥接类

创建一个实现MyNativeCallback的类,它持有NativeScript的JSFunction引用,当原生回调触发时,调用这个JS函数:

import com.tns.Runtime;
import com.tns.JSFunction;

public class CallbackWrapper implements MyNativeCallback {
    private JSFunction jsCallback;

    public CallbackWrapper(JSFunction jsCallback) {
        this.jsCallback = jsCallback;
    }

    @Override
    public void onEventHappened(String eventData) {
        // 确保在NativeScript的主线程执行JS代码,避免线程错误
        Runtime runtime = Runtime.getCurrentRuntime();
        runtime.callJSFunction(jsCallback, null, new Object[]{eventData});
    }
}

步骤2:在插件JS层传递回调

在你的NativeScript插件JS代码中,创建JS回调函数,然后通过桥接类传给原生库:

// 导入原生库类(根据你的插件配置调整路径)
const MyNativeLibrary = require("nativescript-your-plugin").MyNativeLibrary;

// 初始化原生库实例
const nativeLib = new MyNativeLibrary();

// 定义JS回调函数
const myJsCallback = (eventData) => {
    console.log("原生事件触发啦,数据是:", eventData);
    // 这里写你的JS业务逻辑
};

// 创建桥接实例并注册到原生库
const callbackWrapper = new CallbackWrapper(myJsCallback);
nativeLib.registerCallback(callbackWrapper);

关键注意点

  • 线程问题:Android原生库的回调可能在子线程触发,runtime.callJSFunction会自动切换到NativeScript的主线程执行JS,避免跨线程错误。
  • 内存泄漏:如果插件不再使用,记得调用原生库的移除回调方法(如果有的话),防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:14:41