1 回答
TA贡献1875条经验 获得超3个赞
JxBrowser 基于 Chromium 引擎,继承了其多进程架构。每个Browser实例与至少一个处理 DOM 和 JavaScript 相关功能的渲染进程相关联。当您导航到不同的域时,Chromium 引擎会创建一个新的渲染进程并终止旧的渲染进程。如果您在一个域内导航,则呈现过程保持不变。
从调用堆栈中,我看到您尝试从 DOM 侦听器中加载 URL。DOM 侦听器是同步调用的,因此在 Java 处理事件时渲染进程保持阻塞。
当你加载一个 URL 时,例如 google.com,一切正常,因为一个新的渲染进程被创建,并且一旦页面被加载,该Browser.invokeAndWaitFinishLoadingMainFrame方法返回控制并且旧的渲染进程被终止。但是,如果您尝试加载file:///URL,则渲染过程保持不变,并且无法开始加载,因为渲染过程被Browser.invokeAndWaitFinishLoadingMainFrameDOM 侦听器调用的方法阻塞,因此您会遇到死锁。
为了避免此异常,您不应从 DOM 侦听器中启动同步导航。
根据调用堆栈,您loadView从DOMEventListener. 为了避免死锁,您应该异步调用此方法,例如:
import com.teamdev.jxbrowser.chromium.dom.events.DOMEvent;
import com.teamdev.jxbrowser.chromium.dom.events.DOMEventListener;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyDomEventListener implements DOMEventListener {
private final ExecutorService executorService;
private final OrderCreationView view;
public MyDomEventListener(OrderCreationView view) {
this.view = view;
this.executorService = Executors.newCachedThreadPool();
}
@Override
public void handleEvent(DOMEvent domEvent) {
// Do not block the current thread and invoke the loadView method asynchronously.
executorService.execute(view::loadView);
}
}
在该loadView方法中,您可以同步加载 HTML:
public void loadView() {
Browser.invokeAndWaitFinishLoadingMainFrame(browser, new Callback<Browser>() {
@Override
public void invoke(Browser browser) {
browser.loadHTML("");
}
});
initLoginButton();
}
添加回答
举报