Javafx的WebEngine的url加载不输出结果坑,gc回收了局部变量
一、坑場景復現
源于w3cschool的JavaFX WebEngine測試例子,運行代碼都沒有輸出,一直在研究為什么會出現這樣的結果。
在測試過程中使用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="<html>\n" +"\n" +"<head>\n" +"<title>我的第一個 HTML 頁面</title>\n" +"</head>\n" +"\n" +"<body>\n" +"<p>body 元素的內容會顯示在瀏覽器中。</p>\n" +"<p id='a'>title 元素的內容會顯示在瀏覽器的標題欄中。</p>\n" +"</body>\n" +"<script>var a =document.getElementById('a');\n" +"a.style.color='red';</script>\n" +"</html>\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><head> <title>我的第一個 HTML 頁面</title> </head><body> <p>body 元素的內容會顯示在瀏覽器中。</p> <p id="a" style="color: red;">title 元素的內容會顯示在瀏覽器的標題欄中。</p><script>var a =document.getElementById('a'); a.style.color='red';</script></body></html>Process finished with exit code 02、WebEngine 加載url:
SCHEDULED RUNNING finish程序運行不能結束。
如果在WebEngin類的dispatchLoadEvent(long frame, int state, String url, String contentType, double workDone, int errorCode)方法里面debug運行,則輸出
SCHEDULED RUNNING finish <html> ...//內容太多此處省略 </html>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} }?
總結
以上是生活随笔為你收集整理的Javafx的WebEngine的url加载不输出结果坑,gc回收了局部变量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “抖音商城双11好物节”:单品立减15%
- 下一篇: JavaFX图表(二)之饼图