【问题标题】:JCEF functions only work from the second call onwards (Java Chromium Embedded Framework)JCEF 函数仅从第二次调用开始起作用(Java Chromium Embedded Framework)
【发布时间】:2020-10-01 08:32:50
【问题描述】:

我最近将 Java Chromium Embedded Framework (https://github.com/chromiumembedded/java-cef) 集成到 Netbeans (RCP) 应用程序项目(Java:JDK11)中。

浏览器窗口显示在 Netbeans TopComponent 中,通常可以正常工作。

但是,我注意到了几个很小但令人讨厌的错误,它们始终遵循相同的模式: 无论我执行什么涉及 jcef 浏览器的代码,总是只在我第二次执行它时才有效,并且在第一次时几乎被忽略。 但是没有错误消息或日志或任何类似的东西,当我使用调试工具检查代码时,代码似乎已被执行。

三个例子:

  1. 实现一个返回按钮:
    这只是检查 CefBrowser 实例是否返回truebrowser.canGoBack()。如果它返回true,则激活一个按钮。
    该值正确地从false开始,但在第二次更改url后返回true。(显然应该在第一次更改之后发生)
    从那里开始它工作得很好....除非您返回(使用返回按钮)到主页。然后它显然应该再次返回false - 它没有。
    再次调用不同的URL返回false for canGoBack()(这显然应该是true)并且只在之后返回true第二个 URL 再次更改。
    因此,canGoBack 的返回值始终显示它应该从上一次执行中显示的返回值,好像落后了一次。
  2. 实现一个“转到”功能:
    这个功能只是把你带到一个指定的其他网站而不是主页。从第二次开始再次正常工作,但第一次代码被简单地忽略了。 (尽管我通过 Debugger 确认代码即使第一次执行也没有错误)
  3. 实现登录对话框:
    如果浏览器注意到需要身份验证,则会打开一个对话框,用户可以在其中输入 BASIC 凭据。
    对话框再次打开,凭据是正确返回(通过日志确认),被移交给适当的函数,它适用于第二次尝试,但不适用于第一次。 (凭据相同)
    事实上,我通过 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;
            }
        });

遗憾的是,我不知道是什么原因导致了这些问题。

如果你们中的任何人遇到过同样的问题,或者对如何解决它们有任何想法,或者甚至从哪里开始寻找解决方案,我将非常感谢你们的 cmets。

提前致谢!

【问题讨论】:

  • 你试过JCEF forum吗?
  • 感谢您的提示。我确实尝试搜索该论坛,但没有发现很多类似的问题。 (听起来相似的那些也不起作用)我可能也应该在那里发布这个问题。
  • 由于我在 jcef 论坛上没有找到任何关于这个特定主题的帖子,很可能这个问题实际上是由在 Netbeans RCP 中运行的 jcef 引起的。这肯定不是 Netbeans RCP 第一次干扰其他事情了……

标签: java java-11 chromium-embedded netbeans-platform


【解决方案1】:

我找到了上述问题的答案。万一其他人将来会偶然发现类似问题,我将简要总结一下为我解决了什么问题。

显然,我遇到的大多数问题都来自线程问题。似乎当您在 jcef 浏览器上执行命令时,它的线程仍在处理某事,您的命令将不会被执行,但也不会出现任何错误消息或其他不需要的行为。

第二个问题的例子: 执行go(url) 命令时,浏览器尚未完全加载初始主页。这就是该命令被忽略的原因。 为了解决这个问题,我添加了一个简单的字符串变量,它将保存某人想要加载的 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 页面的官方详细示例代码中。 这个问题似乎又是线程问题,但这次我不确定。 作为一种解决方法,我实施了以下解决方案:

  • 为用户名和密码添加类变量
  • 如果这些变量为空,则在 getAuthCredentials 方法中启动登录对话框(参见原始问题)并将给定的用户名和密码保存在这些类变量中。
  • 然后执行browser.reload();
  • 浏览器将再次进行身份验证,但这一次变量不会为空,您可以将它们交给callback.Continue(username, password);,这样只会向用户显示一个登录对话框。

这个过程也很快,所以用户希望能够注意到重新加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2018-04-25
    相关资源
    最近更新 更多