java - 从 URL 线程解析 JavaFX JSON 冻结 UI
问题描述
我让这个任务在一个线程中运行。问题是它每次执行时都会冻结 UI。当互联网速度较慢时,冻结时间会更长。即使 UI 仍在从 url 收集数据,如何防止 UI 冻结?
Task<Void> task = new Task<Void>(){
@Override
public Void call() throws Exception {
while (true) {
Platform.runLater(new Runnable() {
@Override
public void run(){
String json = null;
try {
psname = null;
PumpSites n = table.getSelectionModel().getSelectedItem();
psname = n.getPs();
if(psname == "Cubacub")
json = readUrl(""); //read json from thingspeak.com webpage
else if(psname == "Canduman")
json = readUrl("");
} catch (InterruptedIOException iioe)
{
btn1.setTextFill(Color.RED);
btn2.setTextFill(Color.RED);
btn3.setTextFill(Color.RED);
btn4.setTextFill(Color.RED);
btn5.setTextFill(Color.RED);
btn1.setText("NULL");
btn2.setText("NULL");
btn3.setText("NULL");
btn4.setText("NULL");
btn5.setText("NULL");
}
catch (IOException ioe)
{
btn1.setTextFill(Color.RED);
btn2.setTextFill(Color.RED);
btn3.setTextFill(Color.RED);
btn4.setTextFill(Color.RED);
btn5.setTextFill(Color.RED);
btn1.setText("NULL");
btn2.setText("NULL");
btn3.setText("NULL");
btn4.setText("NULL");
btn5.setText("NULL");
}
catch (Exception e1) {
btn1.setTextFill(Color.RED);
btn2.setTextFill(Color.RED);
btn3.setTextFill(Color.RED);
btn4.setTextFill(Color.RED);
btn5.setTextFill(Color.RED);
btn1.setText("NULL");
btn2.setText("NULL");
btn3.setText("NULL");
btn4.setText("NULL");
btn5.setText("NULL");
}
Gson gson = new Gson();
Page page = gson.fromJson(json, Page.class);
for (Item item : page.feeds)
{
det2 = 1;
btn1.setText(item.field1);
btn2.setText(item.field2);
btn3.setText(item.field3);
btn4.setText(item.field4);
btn5.setText(item.field5);
f2 = Float.parseFloat(item.field2);
f3 = Float.parseFloat(item.field3);
//float f5 = Float.parseFloat(item.field5);
if (f2 <= 10.0)
{
btn1.setTextFill(Color.RED);
btn2.setTextFill(Color.RED);
}
else
{
btn1.setTextFill(Color.BLUE);
btn2.setTextFill(Color.BLUE);
}
if (f3 < 0.9 || f3 > 1.2)
{
btn3.setTextFill(Color.RED);
}
else
{
btn3.setTextFill(Color.BLUE);
}
/*if (f5 > 5.0)
{
btn5.setTextFill(Color.RED);
}
else
{
btn5.setTextFill(Color.BLUE);
}*/
btn4.setTextFill(Color.BLUE);
}
if(det2 == 0)
{
btn1.setTextFill(Color.RED);
btn2.setTextFill(Color.RED);
btn3.setTextFill(Color.RED);
btn4.setTextFill(Color.RED);
btn5.setTextFill(Color.RED);
btn1.setText("NULL");
btn2.setText("NULL");
btn3.setText("NULL");
btn4.setText("NULL");
btn5.setText("NULL");
}
det2 = 0;
}
});
Thread.sleep(10000);
}
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
问题是它每次执行时都会冻结 UI。当互联网速度较慢时,冻结时间会更长。即使 UI 仍在从 url 收集数据,如何防止 UI 冻结?
解决方案
UI 线程冻结,因为您仍在 JavaFX 应用程序线程 ( Platform.runLater ) 上执行所有逻辑。
你应该这样做:
public Void call() throws Exception
{
while (true)
{
try
{
//get json
} catch(Exception e)
{
Platform.runLater(new Runnable()
{
@Override
public void run()
{
//set buttons color and text here
}
}
}
//Rest of your logic here
}
}
这个想法是,所有要从单独的线程修改 UI 组件的事情都应该在Platform.runLater
推荐阅读
- tsql - SQL 数据仓库和 Tableau 中的时态表和时间维度
- vue.js - 嵌套路由上的活动类
- python - 为什么我的 discord.py 事件没有被调用?
- python - 从类参数创建列表(类变量)
- python - 加快文本处理步骤
- rabbitmq - x 时间段后自动删除 Rabbit MQ 队列
- vue.js - Vue Storybook 动态故事
- java - 使用 JSOUP java 抓取数据时如何防止死超时?
- visual-studio-code - 如何在 Visual Studio 代码上修复 ctrl+f
- javascript - 标记其他复选框 onClick