Dat*_*uti 4 javascript bridge javafx jar jsobject
问题
我花了几个小时试图确定我的分布式代码失败的原因,但是在使用IDE(NetBeans)调试时我的源代码没有问题.我找到了一个解决方案,并发帖帮助其他可能有类似问题的人.顺便说一句:我是一个自学成才的程序员,可能会缺少一些基本概念 - 随时教育我.
背景资料
在JavaFX应用程序中使用WebView控件我从html文件加载网页.我想使用JavaScript来处理HTML方面,但我还需要在Java和JavaScript之间自由传递信息(两个方向).非常适合使用WebEngine.executeScript()方法进行Java启动的传输,并使用Java中的JSObject.setMember()为JavaScript启动向Java传输信息的方法.
设置链接(这种方式稍后会破坏):
/*Simple example class that gives method for
JavaScript to send text to Java debugger console*/
public static class JavaLink {
public void showMsg(String msg) {
System.out.println(msg);
}
}
...
/*This can be added in the initialize() method of
the FXML controller with a reference to the WebEngine*/
public void initialize(URL url, ResourceBundle rb) {
webE = webView.getEngine();
//Retrieve a reference to the JavaScript window object
JSObject jsObj = (JSObject)webE.executeScript("window");
jsObj.setMember("javaLink", new JavaLink());
/*Now in our JavaScript code we can type javaLink.showMsg("Hello!");
which will send 'Hello!' to the debugger console*/
}
Run Code Online (Sandbox Code Playgroud)
上面的代码将很有用,直到分发它并尝试运行JAR文件.经过几个小时的搜索和测试不同的调整,我最终将问题缩小到JavaLink对象本身(我最终了解到你可以在JavaScript中使用try-catch块,这使我能够捕获错误:" TypeError:showMsg不是一个函数. .. ").
解决方案
我发现声明一个全局变量来保存JavaLink类的实例并将其作为参数传递到setMember()方法中进行修复,以便应用程序现在既可以在IDE中运行,也可以在独立的JAR中运行:
JavaLink jl;
...
jl = new JavaLink();
//replace anonymous instantiation of JavaLink with global variable
jsObj.setMember("javaLink", jl);
Run Code Online (Sandbox Code Playgroud)
为什么!?
我猜这与垃圾收集有关,除非你通过声明一个全局变量来强制它,否则JVM不会保留对JavaLink的引用.还有其他想法吗?
| 归档时间: |
|
| 查看次数: |
1033 次 |
| 最近记录: |