- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
来自WebEngine文档:
Loading always happens on a background thread. Methods that initiate loading return immediately after scheduling a background job. To track progress and/or cancel a job, use the Worker instance available from the getLoadWorker() method.
我有一个 HTML string我通过 WebEngine.loadContent(String)
在 WebView 上加载它。该字符串大约有 500 万个字符长。在 Platform.runLater()
中运行它时(我必须在 JavaFX 线程中运行它,否则会出现错误)我的 UI 挂起大约一分钟。
如果我不在 Platform.runLater()
中运行它,我会得到:
java.lang.IllegalStateException: Not on FX application thread; currentThread = populator
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.web.WebEngine.checkThread(WebEngine.java:1216)
at javafx.scene.web.WebEngine.loadContent(WebEngine.java:931)
at javafx.scene.web.WebEngine.loadContent(WebEngine.java:919)
...
因为我必须,再次在挂起的 JavaFX 线程上运行它...
所以我必须等到页面加载,然后之前提交的任何Platform.runLater(()->webEngine.getLoadWorker().getProgress())
(在网页加载过程中)会运行,每次给我 1.0...
我用来查询 Worker 的代码:
// WebView
wvIn.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
class ProgressThread extends Thread {
private Worker.State loadWorkerState;
synchronized Worker.State getLoadWorkerState() {
return loadWorkerState;
}
synchronized void setLoadWorkerState(Worker.State loadWorkerState) {
this.loadWorkerState = loadWorkerState;
}
{
setDaemon(true);
setName("LoadingWebpageProgressThread");
}
public void run() {
while (true) {
try {
if (getLoadWorkerState() == Worker.State.RUNNING)
// piWv ProgressIndicator (WebView loading)
Platform.runLater(() -> piWv.setVisible(true));
while (getLoadWorkerState() == Worker.State.RUNNING) {
Platform.runLater(() -> {
piWv.setProgress(wvIn.getEngine().getLoadWorker().getProgress());
// TODO delete
System.out.println(wvIn.getEngine().getLoadWorker().getProgress());
});
Thread.sleep(100);
}
if (getLoadWorkerState() == Worker.State.SUCCEEDED) {
Platform.runLater(() -> piWv.setProgress(1d));
Thread.sleep(100);
Platform.runLater(() -> {
piWv.setVisible(false);
piWv.setProgress(0d);
});
}
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
}
}
}
};
final ProgressThread progressThread = new ProgressThread();
{
progressThread.start();
}
// executed on JavaFX Thread
@Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
if (newValue == State.SUCCEEDED) {
JSObject window = (JSObject) wvIn.getEngine().executeScript("window");
window.setMember("controller", mainController);
progressThread.setLoadWorkerState(newValue);
progressThread.interrupt();
} else if (newValue == State.RUNNING) {
progressThread.setLoadWorkerState(newValue);
progressThread.interrupt();
}
// TODO delete
System.out.println(oldValue + "->" + newValue);
}
});
有没有办法在后台线程中强制加载?
JavaFX 线程中到底发生了什么?是填充WebView的过程吗?
最佳答案
您在问题中显示的 HTML 文件几乎立即加载到我的机器上。
在我看来,问题出在您的代码中。好吧,这很麻烦。请让我指出它看起来不太好,因为它是 deadlock -prone,并使用异常来实现 guarded-blocks 的形式.
看来你没有完全理解 events 的概念.除非您为了简洁起见以某种方式切断了问题中的代码片段,否则 ProgressThread
实例是完全无用的。你已经有一个 ChangeListener
根据需要分派(dispatch)事件,在 JavaFX 应用程序线程上执行回调;只需使用它。
indicator.setVisible(false); // Start hidden
engine.getLoadWorker().progressProperty().addListener((observable, oldValue, newValue) -> {
indicator.setProgress(newValue.doubleValue());
indicator.setVisible(indicator.getProgress() != 1D);
});
或者,您可以使用 binding 的强大功能:
Worker<Void> worker = engine.getLoadWorker();
indicator.visibleProperty().bind(worker.stateProperty().isEqualTo(Worker.State.RUNNING));
indicator.progressProperty().bind(worker.progressProperty());
对于您的 JavaScript 代码,我建议您监听文档事件而不是工作状态事件:它们在您的情况下更有意义,并且在页面实际完成呈现时触发它们,而不仅仅是在页面数据完成时触发下载中。
engine.documentProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null) {
return;
}
JSObject window = (JSObject)engine.executeScript("window");
window.setMember("controller", mainController);
});
请注意,在我的机器上,加载过程中进度似乎始终为零。我认为问题出在您的 HTML 代码中:如果您尝试加载一些其他资源,例如我们正在阅读的网页,进度指示器将提供更愉快的体验,在页面内容完成之前更新几次加载中。
关于Javafx WebEngine : what really happens in a background worker? UI 在 loadContent(大 HTML 文档)上挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41830701/
我试图“真正”理解进程和线程 - 我读过有关它们的书籍和文章,但总体情况似乎总是缺少一些东西。当然,我可以喋喋不休地谈论细节,例如每个进程如何拥有自己的内存空间以及属于同一进程的线程如何共享相同的内存
在 Perl 的描述中 -i[extension]功能在 http://perldoc.perl.org/perlrun.html ,与以下程序实质上相同的代码被视为使用 perl -pi.orig
我目前正在下类后的空闲时间参加 Coursera 上的 Scala 类(class),试图最终尝试函数式编程。我目前正在处理一项任务,我们应该“计算”包含某个对象的两个集合的并集。我有意省略了细节,因
这里有人说会开放攻击 How do you serialize javascript objects with methods using JSON 这对我来说是一个相当肤浅的答案,因为为什么它比经典
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
我正在尝试使用 glsl 在 GPU 中实现图像处理算法,如高斯滤波、双边滤波。 我对哪一部分是“真正的”并行执行感到困惑。例如,我有一个 1280*720 的预览作为纹理。我不太确定哪个部分真正运行
你好 不要说这是一个重复的问题,因为我已经阅读了两天。他们中没有一个真正提供有用的答案。 我在 SD 卡上的一个文件夹中有许多不同的文件。想要根据 apk、txt、mp3、avi、jpg 打开正确的应
我正在尝试使用以下代码保存一些代码。我有一个对象,其中的变量与表行的名称相同,因此我可以创建一个像这样的插入: $query = "INSERT INTO table "; $colu
使用 Qt 我知道 private slots 意味着插槽在直接调用时是私有(private)的,但是 connect() 仍然可以允许信号连接到插槽是否私有(private),公开的,或者我猜, p
考虑以下语句: int *pFarr, *pVarr; int farr[3] = {11,22,33}; int varr[3] = {7,8,9}; pFarr = &(farr
我一直在使用 static 关键字来定义内部链接。后来,我改用 C++ 风格,将本地事物包装在匿名命名空间中。 然而,当我使用匿名命名空间多年后,我开始认为 static 关键字更容易使用! 一个常见
我正在尝试使用 ffmpeg 和 对 DVD 质量的视频进行编码nl 表示 过滤(嗯,这就是标题所说的)。但即使在顶级 Core i7 CPU 上,我每秒也只有 12 帧,并且只有一个内核在使用(75
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我正在构建我的第一个 Backbone.js 应用程序,但我很困惑我应该向 View 赋予或隐藏多少责任。 在我的示例中,我正在构建一个从集合动态生成的丰富 UI 表(类似于 YUI 的数据网格)。在
新手用户使用 Azure Linux VM,发现删除 VM(停止计费的必要步骤)会留下难以识别和区分的存储残余,这些残余与我想要保留的 Blob(支持 VM 镜像和数据磁盘) , 例如)。 所以我真的
当我在 NetBeans (7.1.2) 中添加组件或任何自动生成注释的内容时,注释每行一个单词。像这样: /* * If * Nimbus * (introduced
我将这个海龟文件加载到两个不同的 OWL 推理器(HermiT 和 RDFox)中: @prefix : . @prefix owl: . @prefix rdf: . @prefix rdfs
我的问题很简单,但(我猜)很难回答: 我的 PHP 网站/Web 应用程序中真的需要完整的模型- View - Controller 设计模式吗? 我无法理解 Controller 如何与 PHP 一
新手用户使用 Azure Linux VM,发现删除 VM(停止计费的必要步骤)会留下难以识别和区分的存储残余,这些残余与我想要保留的 Blob(支持 VM 镜像和数据磁盘) , 例如)。 所以我真的
我将这个海龟文件加载到两个不同的 OWL 推理器(HermiT 和 RDFox)中: @prefix : . @prefix owl: . @prefix rdf: . @prefix rdfs
我是一名优秀的程序员,十分优秀!