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();
}
添加回答
舉報