变量更改时更新UI

时间:2014-11-19 20:22:29

标签: java android multithreading performance asynchronous

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

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

更新用户界面的最有效方法是什么?

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

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

还有另一种方法,而不是实现一个自己的'变量改变'听众?

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

我认为类似的东西适用于您描述的系统并减少抖动。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

  

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

然后将更新拆分为十个部分,每10毫秒运行一部分。

从另一个答案:

  

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

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

  

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

简单的解决方案是:

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

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