JCEF-JS与JAVA代码交互
实现JS与JAVA代码交互是做应用所必须的一步。通过JS调用JAVA代码实现一切JAVA代码能实现的东西。可查阅 org.cef.browser.CefMessageRouter 类的文档。api文档(中英文) https://pan.baidu.com/s/18eioiDbIPM5aDdyn0TatVA 提取码: aptd因为是异步方式要获取java代码的处理结果需要在回调处理结果。应该大多数人都不喜欢这种形式的调用。如果和JAVA代码交互步骤很多JS代码会一层套一层很不雅观。我们可以通过js的 Promise 来解决这个问题。JAVA代码实现/** * Js与Java代码交互测试 * author liuming */ public class JsTestFrame extends JFrame{ /** * */ private static final long serialVersionUID -9131822589633996915L; public static void main(String[] args) { //必须在main()方法的开头调用此方法才能执行特定于平台的启动初始化。在Linux上这将初始化Xlib多线程而在macOS上这会动态加载CEF框架。 if (!CefApp.startup(args)) { System.out.println(Startup initialization failed!); return; } String urlSystem.getProperty(user.dir)/view/jstest.html; new JsTestFrame(url); } public JsTestFrame(String url) { //是否Linux系统 boolean useOSROS.isLinux(); //是否透明 boolean isTransparentfalse; //添加Handler在CEFAPP状态为终止时退出程序 CefApp.addAppHandler(new CefAppHandlerAdapter(null) { Override public void stateHasChanged(org.cef.CefApp.CefAppState state) { // Shutdown the app if the native CEF part is terminated if (state CefAppState.TERMINATED) System.exit(0); } }); CefSettings settings new CefSettings(); settings.windowless_rendering_enabled useOSR; //获取CefApp实例 CefApp cefAppCefApp.getInstance(settings); //创建客户端实例 CefClient cefClient cefApp.createClient(); //添加一个JS交互 jsActive(cefClient); //创建浏览器实例 CefBrowser cefBrowser cefClient.createBrowser(url, useOSR, isTransparent); //将浏览器UI添加到窗口中 getContentPane().add(cefBrowser.getUIComponent(), BorderLayout.CENTER); pack(); setTitle(测试JCEF-JS与JAVA代码交互); setSize(800, 600); setVisible(true); //添加一个窗口关闭监听事件 addWindowListener(new WindowAdapter() { Override public void windowClosing(WindowEvent e) { CefApp.getInstance().dispose(); dispose(); } }); } /** * 添加js交互 * author:liuming */ public void jsActive(CefClient client) { //配置一个查询路由,html页面可使用 window.java({}) 和 window.javaCancel({}) 来调用此方法 CefMessageRouterConfig cmrcnew CefMessageRouterConfig(java,javaCancel); //创建查询路由 CefMessageRouter cmrCefMessageRouter.create(cmrc); cmr.addHandler(new CefMessageRouterHandler() { Override public void setNativeRef(String str, long val) { System.out.println(str val); } Override public long getNativeRef(String str) { System.out.println(str); return 0; } Override public void onQueryCanceled(CefBrowser browser, CefFrame frame, long query_id) { System.out.println(取消查询:query_id); } Override public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String request, boolean persistent, CefQueryCallback callback) { System.out.println(request:request\nquery_id:query_id\npersistent:persistent); //如果传的字符串是 暂停 休眠2秒 if(暂停.equals(request)){ try { Thread.sleep(2000L); } catch (InterruptedException e) { throw new RuntimeException(e); } } callback.success(Java后台处理了数据!这是您传给JAVA后台的数据request); return true; } }, true); client.addMessageRouter(cmr); } }html实现在工程根目录新建 jstest.html注意有些jcef版本使用 alert() 会导致程序闪退在项目中尽量避免使用原生的alert、confirm函数而使用UI框架的弹窗函数!DOCTYPE html html langzh-CN head titleJCEF帮助文档/title meta charsetutf-8 meta namerenderer contentwebkit meta http-equivX-UA-Compatible contentIEedge meta nameviewport contentwidthdevice-width, initial-scale1 /head body a hrefjavascript:testToJava()测试与java代码交互/a br br a hrefjavascript:testToJava2()测试与java代码交互(同步的方式)/a brbr a hrefjavascript:testToJava3()测试与java代码交互(同步的方式-1)/a div stylecolor:red;注意有些jcef版本使用 alert() 会导致程序闪退在项目中尽量避免使用原生的alert、confirm函数而使用UI框架的弹窗函数本文章将原来的alert换为了直接输出到页面上 /div div idlog /div /body script function testToJava(){ window.java({ request: 发送给JAVA的数据, persistent:false, onSuccess: function(response) { logPrint(返回的数据:response); }, onFailure: function(error_code, error_message) { //失败处理 } }); } /*** * 返回一个Promise对象再利用await实现js与java交互的同步处理 */ function execJava(data){ return new Promise(function(resolve, reject) { window.java({ request: data, persistent:false, onSuccess: function(response) { resolve(response); }, onFailure: function(error_code, error_message) { //失败处理 } }); }); } /*** * 此函数需要使用 async 声明 */ async function testToJava2(){ var dataawait execJava(第一个调用两秒后打印下一个调用的结果); logPrint(返回的数据data); dataawait execJava(暂停); logPrint(返回的数据data); } function testToJava3(){ execJava(第一个调用) .then(function(data){ logPrint(返回的数据data); return execJava(第二个调用); }) .then(function(data){ logPrint(返回的数据data); }); } function logPrint(data){ document.getElementById(log).innerHTMLdocument.getElementById(log).innerHTMLdatabr; } /script !-- author:玄翼猫 -- /html关于JS Promise的使用请自行查阅资料。有两种形式一种是 async await 一种是xx.then(funciton(){}).catch(function(){})。第一种写法让代码看上去是按行运行的比较直观。但是await的使用范围有所限制所以建议使用第二种。-- 这是一个Jcef 的简单 Demo包含JAVA与JS交互鼠标右键菜单以Tab形式展示浏览器。另外包含一个使用jceflayui做的包含 png转ico图片缩放 功能的应用此应用主要用来测试打包在windows下可以使用 打包exe.bat 生成exe安装包其他平台请自行参考jpackage的用法。githubhttps://github.com/lieyanfeimao/JcefTest码云https://gitee.com/edadmin/JcefTest.git