Javafx的WebEngine的url加载不输出结果坑,gc回收了局部变量
发布日期:2021-07-01 01:57:38 浏览次数:2 分类:技术文章

本文共 4408 字,大约阅读时间需要 14 分钟。

一、坑场景复现

源于,运行代码都没有输出,一直在研究为什么会出现这样的结果。

在测试过程中使用WebEngine的html加载,使用WebEngine的url加载,使用WebView加载url,使用仅Scene装载WebView(没有加入Stage或者没有运行stage.show()方法),还有使用Scene装载WebView(加入Stage并且运行stage.show()方法)等等,其中只有WebEngine的html加载Scene装载WebView(加入Stage并且运行stage.show()方法)有输出文档信息,其余都没有输出结果。

 

(1)代码对比

1、WebEngine 加载html

import com.sun.javafx.application.PlatformImpl;import javafx.concurrent.Worker;import javafx.scene.web.WebEngine;public class A {    public static void main(String[] args) throws InterruptedException {        PlatformImpl.startup(()->{            doDom();            System.err.println("finish");        });    }    public static void doDom() {        WebEngine webEngine = new WebEngine();        webEngine.getLoadWorker().stateProperty()                .addListener((obs, oldValue, newValue) -> {                    if (newValue == Worker.State.SUCCEEDED) {                        String html = (String) webEngine                                .executeScript("document.documentElement.outerHTML");                        System.out.println(html);                        System.exit(0);                    }                    System.out.println(newValue + " ");                }); // addListener()        String s="\n" +                "\n" +                "\n" +                "我的第一个 HTML 页面\n" +                "\n" +                "\n" +                "\n" +                "

body 元素的内容会显示在浏览器中。

\n" + "

title 元素的内容会显示在浏览器的标题栏中。

\n" + "\n" + "\n" + "\n"; webEngine.loadContent(s); }}

2、WebEngine 加载url

import com.sun.javafx.application.PlatformImpl;import javafx.concurrent.Worker.State;import javafx.scene.web.WebEngine;public class Test {    public static void main(String[] args) throws InterruptedException {              PlatformImpl.startup(() -> {            doDom();            System.err.println("finish");        });    }    public static void doDom(){        WebEngine webEngine = new WebEngine();        webEngine.getLoadWorker().stateProperty()                .addListener((obs, oldValue, newValue) -> {                    if (newValue == State.SUCCEEDED) {                        String html = (String) webEngine                                .executeScript("document.documentElement.outerHTML");                        System.out.println(html);                        System.exit(0);                    }                    System.out.println(newValue + " ");                }); // addListener()        webEngine.load("https://www.w3cschool.cn/java/javafx-webengine.html");    }}

(2)输出结果

1、WebEngine 加载html:

SCHEDULED RUNNING finish我的第一个 HTML 页面

body 元素的内容会显示在浏览器中。

title 元素的内容会显示在浏览器的标题栏中。

Process finished with exit code 0

2、WebEngine 加载url:

SCHEDULED RUNNING finish

程序运行不能结束。

如果在WebEngin类dispatchLoadEvent(long frame, int state, String url, String contentType, double workDone, int errorCode)方法里面debug运行,则输出

SCHEDULED RUNNING finish...//内容太多此处省略Process finished with exit code 0

 

二、分析原因

通过run和debug模式的运行的结果不同,让我意识到WebEngine 变量是局部变量,里面的监听事件还没有执行完就被gc回收。

备注:Stage primaryStage是局部变量,没有调用show方法,很快就被gc回收,里面包含的WebEngine、WebView和Scene也会被gc回收,故看不到输出。

以前还有遇见过这样的现象,比如Javafx的MediaPlayer播放几秒钟音乐就停止了,因为这个有播放声音比较明显,可以找到是gc回收了MediaPlayer。

import com.sun.javafx.application.PlatformImpl;import javafx.concurrent.Worker.State;import javafx.scene.web.WebEngine;  public class Test {     public static void main(String[] args) throws InterruptedException {         PlatformImpl.startup(() -> {            doDom();            System.out.println("finish");         });    }     static WebEngine webEngine;//webEngine必须要有引用在使用,不能定义成局部变量,否则被gc回收就没有输出结果     public static void doDom(){         //WebEngine webEngine = new WebEngine();//以前定义成局部变量,被gc回收了        webEngine = new WebEngine();        webEngine.getLoadWorker().stateProperty()                .addListener((obs, oldValue, newValue) -> {                    if (newValue == State.SUCCEEDED) {                        String html = (String) webEngine                                .executeScript("document.documentElement.outerHTML");                        System.out.println(html);                        System.exit(0);                    }                    System.out.println(newValue + " ");                }); // addListener()         webEngine.load("https://www.w3cschool.cn/java/javafx-webengine.html");        //webEngine.loadContent(html);//直接加载html     }}

 

转载地址:https://maokun.blog.csdn.net/article/details/85221621 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:易百教程——JavaFX教程
下一篇:javafx爬取网页并且初始化网页数据

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月11日 07时18分09秒