【问题标题】:Updating UI when variable changes变量更改时更新 UI
【发布时间】:2015-01-17 12:39:30
【问题描述】:

我有大约 50 个变量通过网络以大约 1kHz 的速率更新,但它们的值每隔几秒就会改变一次。

这些值用于 UI(例如,按钮的文本、可见性和背景颜色)。

更新 UI 最有效的方法是什么?

我之前在设置所有 UI 变量的 UI 线程上每 100 毫秒运行一次任务。我的问题是每 100 毫秒其他任务的抖动。

我正在寻找仅在变量发生变化时更新 UI 的解决方案。

除了实现自己的“变量更改”侦听器之外,还有其他方法吗?

【问题讨论】:

    标签: java android multithreading performance asynchronous


    【解决方案1】:

    这是计算机科学中的一个常见问题,四人帮已经解决了这个问题。使用 Observer/Observable 模式来识别更改。 Android 还有一些实现MVC(适配器和ListViews...)的内置模块。

    【讨论】:

    • 我一定要调查一下。我没听说过 Observable :)
    【解决方案2】:

    我相信实现“变量更改”侦听器可能是最正确(也是最有效)的实现方式,但您始终可以将当前显示在 UI 中的值与更改之前在网络上更新的值进行比较用户界面。

    if(!label.getText().equals(networkVal)) {
        label.setText(networkVal);
    }
    

    我认为类似的方法可以与您描述的系统一起使用并减少抖动。

    【讨论】:

    • thx 我将尝试仅在 UI 线程中运行 .setText()。我将 .getText().equals() 保留在普通线程中。你觉得这个想法好吗?顺便说一句:用户界面不需要很快
    • 在 UI 线程上做这一切的障碍是什么?在与集合不同的线程中进行检查将导致竞争条件。 en.wikipedia.org/wiki/Race_condition
    【解决方案3】:

    您可以尝试使用 websocket 或长轮询。

    What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet 讨论得很好。

    【讨论】:

    • 感谢您的回答,但我认为这不适用于 java
    【解决方案4】:

    您可能需要考虑对变量使用 setter 方法并在这些方法中更新小部件。

    【讨论】:

      【解决方案5】:

      我之前在设置所有 UI 变量的 UI 线程上每 100 毫秒运行一次任务。对我来说,问题是每 100 毫秒其他任务的抖动。

      然后将更新分成十个部分,每 10 ms 运行一个部分。

      从另一个答案:

      您始终可以将当前显示在 UI 中的值与更改 UI 之前在网络上更新的值进行比较。

      我不会这样做。这意味着经常访问组件并获得它们的价值可能是昂贵和复杂的,因为它们属于 AWT-Thread。如果您的模型包含int,那么从 GUI 获取值可能包括解析,这会不必要地减慢它的速度。

      我将 .getText().equals() 保留在普通线程中。 如果这个线程是唯一更新值的线程,这将起作用。这是不正确的,因为您应该在 AWT 线程上进行所有更新。这可能会导致问题。

      简单的解决办法是:

      • 维护变量的副本。
      • 不时将一些变量与副本进行比较(以便总共每 100 毫秒检查一次所有变量)。
      • 如果有任何差异,请更新 GUI(使用 SwingUtilities.invokeLater)并更新副本(通常)。

      观察者模式是更好但更冗长的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-08
        • 2020-11-10
        • 2017-09-24
        • 2015-11-01
        • 2020-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多