如何从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
相关产品推荐
相关产品推荐

