JCEF 函数仅从第二次调用开始起作用(Java Chromium Embedded Framework)
JCEF functions only work from the second call onwards (Java Chromium Embedded Framework)
我最近在 Netbeans (RCP) 应用程序项目(Java:JDK11)中集成了 Java Chromium 嵌入式框架(https://github.com/chromiumembedded/java-cef)。
浏览器 Window 显示在 Netbeans TopComponent 中,通常工作正常。
然而,我注意到有几个相当小但令人讨厌的错误,它们总是遵循相同的模式:
我执行的任何与 jcef 浏览器有关的代码总是只在我第二次执行时有效,而在第一次执行时几乎被忽略。
但是,没有错误消息或日志或任何类似的东西,当我使用调试工具检查它时,代码似乎被执行了。
三个例子:
- 实现一个return按钮:
这只是检查CefBrowser实例是否returns true
for browser.canGoBack()
。如果它 returns true
一个按钮被激活。
该值正确地从 false
开始,但它 return 在第二次更改 url。(显然应该在第一个之后发生)
从那里开始它工作得很好......除非你返回(使用 return 按钮)到主页。显然它应该再次 return false
- 它没有。
再次调用不同的 URL returns false
for canGoBack()
(然后显然应该是 true
)并且只有 returns true
在第二个 URL 再次改变之后。
所以 return 来自 canGoBack
始终显示它应该从上一次执行中显示的 return,就好像落后了一次。
- 实现“转到”功能:
此功能只是将您带到主页以外的指定其他网站。再次从第二次开始工作正常,但第一次代码被忽略。 (尽管我通过调试器确认代码即使在第一次执行时也没有错误)
- 实现登录对话框:
如果浏览器注意到需要身份验证,则会打开一个对话框,用户可以在其中输入 BASIC 凭据。
再次打开对话框,return 正确输入凭据(通过日志确认),将其移交给适当的功能,它适用于第二次尝试,但不适用于第一次。 (凭据相同)
事实上,我通过 Wireshark 确认,第一次执行 callback.Continue(ad.getUsername(), ad.getPassword());
时,实际上没有任何内容发送到服务器...
第三个例子的代码:
cefClient_.addRequestHandler(new CefRequestHandlerAdapter() {
@Override
public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean isProxy, String host,
int port, String realm, String scheme, CefAuthCallback callback) {
AuthenticationDialog ad = new AuthenticationDialog();
ad.authenticate(); // Shows Login Dialog
LOGGER.log(Level.INFO, String.format("--->%s:%s", ad.getUsername(), ad.getPassword())); //This confirms that the variables are indeed correct even the first time around
callback.Continue(ad.getUsername(), ad.getPassword());
return true;
}
});
遗憾的是,我不知道是什么可能导致这些问题。
如果你们中的任何人遇到过这些相同的问题,或者对如何解决这些问题有任何想法,或者甚至不知道从哪里开始寻找解决方案,我将非常感谢您的意见。
提前致谢!
我找到了上述问题的答案。以防其他人将来偶然发现类似的问题,我将简要总结一下为我解决的问题。
显然,我遇到的大部分问题都是由线程问题引起的。看起来当你在 jcef 浏览器上执行命令时它的线程仍在处理某些东西,你的命令不会被执行,但也不会有任何错误消息或其他不需要的行为。
第二个问题的例子:
当执行 go(url)
命令时,浏览器尚未完全加载初始主页。这就是命令被忽略的原因。
为了解决这个问题,我添加了一个简单的 String 变量,它将保存某人想要加载的 URL,直到浏览器完成加载上一页。
只有这样 url 才会被加载到浏览器中,然后从变量中删除。
这当然也可以用列表之类的东西来完成,但我想不出一个有用的场景。
检查浏览器是否完成加载应该在 CefLoadHandlerAdapter
.
的覆盖方法 onLoadingStateChange
中完成
client_.addLoadHandler(new CefLoadHandlerAdapter() {
@Override
public void onLoadingStateChange(CefBrowser browser, boolean isLoading,
boolean canGoBack, boolean canGoForward) {
if (!isLoading) {
browser_ready = true;
if (goOnReady != null) {
goURL(goOnReady);
}
}
}
});
原始问题中的第一个示例存在类似问题。
通过 canGoBack
变量激活上述 onLoadingStateChange
中的“后退”按钮最终对我有用。
现在第三个例子(登录对话框显示两次)原来是jcef github页面的官方详细示例代码中也存在的问题。
这个问题好像又是线程的问题,不过这次我不确定。
作为解决方法,我实施了以下解决方案:
- 为用户名和密码添加 class 个变量
- 如果这些变量为空,则在
getAuthCredentials
方法中启动登录对话框(参见原始问题)并将给定的用户名和密码保存在这些 class 变量中。
- 然后执行
browser.reload();
- 然后浏览器将再次通过身份验证,但这次变量不会为空,您可以将它们交给
callback.Continue(username, password);
因此只向用户显示一个登录对话框。
这个过程也非常快,因此用户希望能够注意到重新加载。
我最近在 Netbeans (RCP) 应用程序项目(Java:JDK11)中集成了 Java Chromium 嵌入式框架(https://github.com/chromiumembedded/java-cef)。
浏览器 Window 显示在 Netbeans TopComponent 中,通常工作正常。
然而,我注意到有几个相当小但令人讨厌的错误,它们总是遵循相同的模式: 我执行的任何与 jcef 浏览器有关的代码总是只在我第二次执行时有效,而在第一次执行时几乎被忽略。 但是,没有错误消息或日志或任何类似的东西,当我使用调试工具检查它时,代码似乎被执行了。
三个例子:
- 实现一个return按钮:
这只是检查CefBrowser实例是否returnstrue
forbrowser.canGoBack()
。如果它 returnstrue
一个按钮被激活。
该值正确地从false
开始,但它 return 在第二次更改 url。(显然应该在第一个之后发生)
从那里开始它工作得很好......除非你返回(使用 return 按钮)到主页。显然它应该再次 returnfalse
- 它没有。
再次调用不同的 URL returnsfalse
forcanGoBack()
(然后显然应该是true
)并且只有 returnstrue
在第二个 URL 再次改变之后。
所以 return 来自canGoBack
始终显示它应该从上一次执行中显示的 return,就好像落后了一次。 - 实现“转到”功能:
此功能只是将您带到主页以外的指定其他网站。再次从第二次开始工作正常,但第一次代码被忽略。 (尽管我通过调试器确认代码即使在第一次执行时也没有错误) - 实现登录对话框:
如果浏览器注意到需要身份验证,则会打开一个对话框,用户可以在其中输入 BASIC 凭据。
再次打开对话框,return 正确输入凭据(通过日志确认),将其移交给适当的功能,它适用于第二次尝试,但不适用于第一次。 (凭据相同)
事实上,我通过 Wireshark 确认,第一次执行callback.Continue(ad.getUsername(), ad.getPassword());
时,实际上没有任何内容发送到服务器...
第三个例子的代码:
cefClient_.addRequestHandler(new CefRequestHandlerAdapter() {
@Override
public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean isProxy, String host,
int port, String realm, String scheme, CefAuthCallback callback) {
AuthenticationDialog ad = new AuthenticationDialog();
ad.authenticate(); // Shows Login Dialog
LOGGER.log(Level.INFO, String.format("--->%s:%s", ad.getUsername(), ad.getPassword())); //This confirms that the variables are indeed correct even the first time around
callback.Continue(ad.getUsername(), ad.getPassword());
return true;
}
});
遗憾的是,我不知道是什么可能导致这些问题。
如果你们中的任何人遇到过这些相同的问题,或者对如何解决这些问题有任何想法,或者甚至不知道从哪里开始寻找解决方案,我将非常感谢您的意见。
提前致谢!
我找到了上述问题的答案。以防其他人将来偶然发现类似的问题,我将简要总结一下为我解决的问题。
显然,我遇到的大部分问题都是由线程问题引起的。看起来当你在 jcef 浏览器上执行命令时它的线程仍在处理某些东西,你的命令不会被执行,但也不会有任何错误消息或其他不需要的行为。
第二个问题的例子:
当执行 go(url)
命令时,浏览器尚未完全加载初始主页。这就是命令被忽略的原因。
为了解决这个问题,我添加了一个简单的 String 变量,它将保存某人想要加载的 URL,直到浏览器完成加载上一页。
只有这样 url 才会被加载到浏览器中,然后从变量中删除。
这当然也可以用列表之类的东西来完成,但我想不出一个有用的场景。
检查浏览器是否完成加载应该在 CefLoadHandlerAdapter
.
onLoadingStateChange
中完成
client_.addLoadHandler(new CefLoadHandlerAdapter() {
@Override
public void onLoadingStateChange(CefBrowser browser, boolean isLoading,
boolean canGoBack, boolean canGoForward) {
if (!isLoading) {
browser_ready = true;
if (goOnReady != null) {
goURL(goOnReady);
}
}
}
});
原始问题中的第一个示例存在类似问题。
通过 canGoBack
变量激活上述 onLoadingStateChange
中的“后退”按钮最终对我有用。
现在第三个例子(登录对话框显示两次)原来是jcef github页面的官方详细示例代码中也存在的问题。 这个问题好像又是线程的问题,不过这次我不确定。 作为解决方法,我实施了以下解决方案:
- 为用户名和密码添加 class 个变量
- 如果这些变量为空,则在
getAuthCredentials
方法中启动登录对话框(参见原始问题)并将给定的用户名和密码保存在这些 class 变量中。 - 然后执行
browser.reload();
- 然后浏览器将再次通过身份验证,但这次变量不会为空,您可以将它们交给
callback.Continue(username, password);
因此只向用户显示一个登录对话框。
这个过程也非常快,因此用户希望能够注意到重新加载。