JxBrowser основан на движке Chromium и наследует свою многопроцессорную архитектуру. Каждый экземпляр Browser
связан как минимум с одним процессом рендеринга, который обрабатывает функции, связанные с DOM и JavaScript. Когда вы переходите в другой домен, механизм Chromium создает новый процесс рендеринга и убивает старый. Если вы перемещаетесь в пределах одного домена, процесс рендеринга остается прежним.
Из стека вызовов я вижу, что вы пытаетесь загрузить URL из прослушивателя DOM. Слушатели DOM вызываются синхронно, поэтому процесс рендеринга остается заблокированным, пока событие обрабатывается Java.
Когда вы загружаете URL, например, google.com, все работает просто отлично, потому что создается новый процесс рендеринга, и, как только страница загружается, метод Browser.invokeAndWaitFinishLoadingMainFrame
возвращает управление и старый процесс рендеринга уничтожается. Однако если вы попытаетесь загрузить URL-адрес file:///
, процесс рендеринга останется прежним, и загрузка не может начаться, потому что процесс рендеринга заблокирован методом Browser.invokeAndWaitFinishLoadingMainFrame
, вызванным из прослушивателя DOM, поэтому вы получите тупик .
Во избежание этого исключения не следует запускать синхронную навигацию из приемника 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();
}