【问题标题】:Gluon Connect DataProvider.retrieveList results in IllegalStateExceptionGluon Connect DataProvider.retrieveList 导致 IllegalStateException
【发布时间】:2016-08-03 00:35:10
【问题描述】:

以下代码生成 IllegalStateException - 而不是 FX 应用程序线程 - 。

private void populateListView(){
    GluonObservableList<MyClass> items = DataProvider.retrieveList(restClient.createListDataReader(MyClass.class));
    listview.setItems(items);
}

我猜这是因为将Iterator 中的元素添加到GluonObservableList 的代码没有包含在Platform.runLater() 中,尽管retrieveList() 中有其他调用?

【问题讨论】:

    标签: gluon gluon-mobile


    【解决方案1】:

    必须从 FX 应用程序线程更新 UI 元素(例如列表视图)。 如果从后台线程调用 populateListView(),observableList 在后台更新,导致列表视图尝试从后台更新。

    使用 Platform.runLater 将 observableList 设置为 listview 发生在 FX 线程上,但 observableList 在加载到 listview 后仍会在后台更新。

    new Thread(()->{
        GluonObservableList<MyClass> items = DataProvider.retrieveList(restClient.createListDataReader(MyClass.class));
        //Option 1 
        //listview.setItems(items);
        //Option 2
        //Platform.runLater(()->listview.setItems(items));
        //Option 3
        //items.initializedProperty().addListener((obv,ov,nv)->{
        //    listview.setItems(items);
        //});
        //Option 4
        items.stateProperty().addListener((obvs,ovs,nvs)->{
            if (nvs.equals(ConnectState.SUCCEEDED)) {
                listview.setItems(items);
            }else if(nvs.equals(ConnectState.FAILED)){
                MobileApplication.getInstance().showMessage("Rest API request failed");
            }
        });
    }).start();
    


    选项 1 和选项 2 在数据加载到 observableList 之前更新列表视图。选项 1 和 2 抛出多个异常(选项 1 很丑)。

    选项 3 和选项 4 在加载 observableList 并在 FX 应用程序线程上处理后触发列表视图更新。
    或者,您可以在 Platform.runLater 中包装对 populateListView() 的任何调用

    【讨论】:

    • 我想我的问题应该更准确......实际上我正在使用选项 3,我认为这是应该使用 GluonObservableList 的方式。我只是想知道为什么DataProvider.retrieveList 中的Iterator 没有包含在Platform.runLater() 中,这对我来说非常有意义,例如当您考虑在不更新 UI 的 Thread 中使用它的情况时。
    • 只是添加一个快速注释,直接在 ListView 上设置项目确实很有意义,就像在选项 1 中一样。因为 GluonObservableList 是一个 ObservableList,所以添加到它的任何项目,将自动反映在 ListView 控件中,就像您使用常规 ObservableList 时一样。对 DataProvider.retrieveList 的调用也必须在 FX 应用程序线程上执行。 Gluon Connect 已经在它自己的后台线程中实际检索了列表,因此开发人员没有理由从 FX 应用程序线程之外调用它。
    • 在示例中,我专门调用了 DataProvider 并从选项 1 的后台线程填充列表视图。这会产生错误。如果在 FX 线程上,这将起作用。选项 2 仍然会产生错误,因为仍然从后台调用 DataProvider。 DataProvider 工作得很好,因为不需要去后台线程来请求数据。
    猜你喜欢
    • 2014-06-19
    • 1970-01-01
    • 2017-03-15
    • 2015-04-20
    • 2012-05-09
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    相关资源
    最近更新 更多