首页 > 解决方案 > 从 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 冻结?

标签: javajavafxjavafx-8

解决方案


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


推荐阅读