JavaFX桌面應(yīng)用未響應(yīng)問題解決方案
日常使用軟件的過程中,偶爾會(huì)遇到軟件突然卡住,再點(diǎn)擊幾次就變成“未響應(yīng)”的情況。
在JavaFX應(yīng)用中同樣也會(huì)出現(xiàn)這種情況,在開發(fā)過程中應(yīng)該盡量避免這種情況的出現(xiàn)。
1. “未響應(yīng)”重現(xiàn)
應(yīng)用程序出現(xiàn)“未響應(yīng)”這種情況往往是因?yàn)樵赨I線程中處理一些耗時(shí)的業(yè)務(wù),當(dāng)UI線程在處理耗時(shí)的業(yè)務(wù)時(shí),UI就會(huì)卡住。
下面通過一個(gè)示例(獲取Google頁面title信息)來演示一下“未響應(yīng)”這種情況。
這里使用 jsoup 來抓取Google頁面的title信息,需要引入jsoup的maven依賴:
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.13.1</version> </dependency>
編譯AppService,實(shí)現(xiàn)抓取Google頁面的title信息。
public class AppService { public static final AppService INSTANCE = new AppService(); private AppService() { } public String visitGoogle() { try { Document document = Jsoup.parse(new URL("https://www.google.com"), 10_000); return document.head().getElementsByTag("title").get(0).text(); } catch (Exception e) { return e.getMessage(); } } }
因?yàn)闆]有F墻,這里訪問Google肯定是超時(shí)的,這里設(shè)置了超時(shí)10秒。
接著改造AppUI,當(dāng)點(diǎn)擊Go按鈕的時(shí)候,調(diào)用visitGoogle并將結(jié)果顯示在界面上。
public class AppUI implements Initializable { public Label text; private AppService appService = AppService.INSTANCE; private AppModel model = new AppModel(); @Override public void initialize(URL location, ResourceBundle resources) { text.textProperty().bindBidirectional(model.textProperty()); model.setText("Hello JavaFX."); } public void click(ActionEvent event) { model.setText(appService.visitGoogle()); } }
運(yùn)行JavaFX應(yīng)用,當(dāng)點(diǎn)擊第一個(gè)Go按鈕之后,再點(diǎn)擊其他按鈕界面就會(huì)卡住,出現(xiàn)“未響應(yīng)”的現(xiàn)象。
2. UI線程、業(yè)務(wù)線程分離
前面有提到,出現(xiàn)“未響應(yīng)”這種情況是因?yàn)樵赨I線程中處理一些耗時(shí)的業(yè)務(wù),當(dāng)UI線程在處理耗時(shí)的業(yè)務(wù)時(shí),UI就會(huì)卡住。
所以如果能將UI線程和業(yè)務(wù)線程分開來,這樣就能解決界面卡住的問題了。
改造一下AppUI,將調(diào)用visitGoogle的代碼放到新線程去執(zhí)行。
public void click(ActionEvent event) { new Thread(() -> model.setText(appService.visitGoogle())).start(); }
這里直接采用new的方式創(chuàng)建線程,實(shí)際應(yīng)用中最好是使用線程池。
雖然將業(yè)務(wù)代碼放在新線程中處理解決了界面卡住的問題,但是上面的代碼中,通過model.setText()來改變標(biāo)簽(Label)的文字。
實(shí)際上會(huì)發(fā)現(xiàn)程序運(yùn)行后會(huì)出現(xiàn)異常,一旦我們在非UI線程中嘗試改變UI效果,程序就會(huì)拋出下面的異常。
界面卡住的問題雖然解決了,但又出現(xiàn)了新的問題。
3. 在UI線程更新UI
在UI線程處理業(yè)務(wù)會(huì)導(dǎo)致界面卡住,在業(yè)務(wù)線程更新UI會(huì)出現(xiàn)異常,為了能在業(yè)務(wù)線程中更新UI,JavaFX為開發(fā)者提供了一個(gè)Platform類。
只需要在業(yè)務(wù)線程中,將更新UI的代碼放在這個(gè)類的runLater方法中執(zhí)行即可。
下面再次改造AppUI
public void click(ActionEvent event) { new Thread(() -> { String title = appService.visitGoogle(); Platform.runLater(() -> model.setText(title)); }).start(); }
這里還是將業(yè)務(wù)代碼放在新線程中執(zhí)行,但是涉及UI更新的代碼model.setText()則放在Platform.runLater()里面執(zhí)行。
這樣,就解決了界面卡住以及非UI線程更新UI出現(xiàn)異常的問題了。
通過改造,雖然請求Google超時(shí)了,但是UI并沒有卡住,同時(shí)界面也得到了更新。
所以特別注意,在開發(fā)過程中應(yīng)該盡量避免:
在UI線程中處理業(yè)務(wù)在業(yè)務(wù)線程中更新UI
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android中通過RxJava進(jìn)行響應(yīng)式程序設(shè)計(jì)的入門指南
- Java response響應(yīng)體和文件下載實(shí)現(xiàn)原理
- java實(shí)現(xiàn)響應(yīng)重定向發(fā)送post請求操作示例
- JavaWeb Refresh響應(yīng)頭代碼實(shí)例詳解
- javaweb如何實(shí)現(xiàn)請求和響應(yīng)
- java web請求和響應(yīng)中出現(xiàn)中文亂碼問題的解析
- Java Web請求與響應(yīng)實(shí)例詳解
- Java并發(fā)編程之性能、擴(kuò)展性和響應(yīng)
- 淺談Java響應(yīng)式系統(tǒng)
相關(guān)文章
java8 stream自定義分組求和并排序的實(shí)現(xiàn)
這篇文章主要介紹了java8 stream自定義分組求和并排序的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01Java使用新浪微博API通過賬號密碼方式登陸微博的實(shí)例
這篇文章主要介紹了Java使用新浪微博API通過賬號密碼方式登陸微博的實(shí)例,一般來說第三方App都是采用OAuth授權(quán)認(rèn)證然后跳轉(zhuǎn)之類的方法,而本文所介紹的賬號方式則更具有自由度,需要的朋友可以參考下2016-02-02java設(shè)計(jì)模式責(zé)任鏈模式原理案例詳解
一個(gè)事件需要經(jīng)過多個(gè)對象處理是一個(gè)挺常見的場景,譬如采購審批流程,請假流程,軟件開發(fā)中的異常處理流程,web請求處理流程等各種各樣的流程,可以考慮使用責(zé)任鏈模式來實(shí)現(xiàn)2021-09-09SpringBoot+Jersey跨域文件上傳的實(shí)現(xiàn)示例
在SpringBoot開發(fā)后端服務(wù)時(shí),我們一般是提供接口給前端使用,本文主要介紹了SpringBoot+Jersey跨域文件上傳的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07java如何獲取request中json數(shù)據(jù)
這篇文章主要給大家介紹了關(guān)于java如何獲取request中json數(shù)據(jù)的相關(guān)資料,文中通過代碼示例以及圖文將獲取的方法介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08基于maven使用IDEA創(chuàng)建多模塊項(xiàng)目
這篇文章主要介紹了基于maven使用IDEA創(chuàng)建多模塊項(xiàng)目,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04