【问题标题】:Listview's ArrayAdapter notifydatasetchanged() very slow redrawListview 的 ArrayAdapter notifydatasetchanged() 重绘很慢
【发布时间】:2010-09-27 16:11:59
【问题描述】:

我有一个非常简单的列表,每行有 3 个文本视图字段。我们每 2 秒左右使用来自后台 Web 服务调用 (AsyncTask) 的数据更新它们的值

我们将即将到来的值与当前值进行比较,在适配器上相应地更新它们,最后在需要时调用 notifyDataSetChanged()

问题是重绘变得非常缓慢,因此当我们一次获得超过 3 个更新行时会挂起整个 UI。当然,我们正在使用所有 ListView 众所周知的优化方法,例如 EfficientAdapter 方法( setTag() 和 holder )和 getViewTypecount()/getItemViewType() 。我们还尝试使用 layoutopt 尽可能优化我们的界面,并尝试避免使用 wrap_content 的宽度和高度来减轻负担。

我们也不会对更新进行昂贵的操作,只是标准的东西:更改 TextView 文本、textcolor 和 backgroundcolor 值。

我能看到的唯一奇怪的事情是每行调用 getView() 3-4-5 次,尽管我已经阅读了所有 Romain 的消息 [1] 告诉我这没有错

关于我们如何加快速度的任何想法或提示?

非常感谢!

[1]http://groups.google.com/group/android-developers/browse_thread/thread/4c4aedde22fe4594/aeb04288064f495e?show_docid=aeb04288064f495e

【问题讨论】:

  • 听起来你得到的更新比你能画的要多——你有没有试过把更新频率降低到 10 秒来测试这个?如果这有帮助,您将需要找到一种解决方案,以便在每次更新时从任务中清除队列。如果您考虑到自动垃圾收集最多可能需要 1 秒(希望不会更多)并且其他服务也可能会延迟更新,那么 2 秒是很常见的。
  • 调用是连续的,所以在前一个调用完成后执行新的调用。
  • 垃圾收集器最坏情况需要超过 200 毫秒,与应用程序在每次重绘时经历的 1.5 - 2 秒 UI 挂起相比,这算不了什么。刷新率在这里不受影响,即使我将其提高到 10 秒,在调用被触发后,重绘将继续冻结 2 秒
  • 你尝试过在 AsyncTask 中做这些吗?
  • 使用分析工具怎么样? DDMS 对notifyDataSetChanged() 时间有何看法?哦,我刚刚注意到问题上的日期......你解决了吗?

标签: listview android performance android-arrayadapter redraw


【解决方案1】:

这适用于那些从谷歌浏览并认为他们需要重写自己的数据更改方法的人。根据我的数据,很多情况下不需要。

notifyDataSetChanged() 可能比您手动编码的替换要快得多,这完全取决于您实际的 listview 实现。

示例:一个简单的 3 行纯文本列表视图,最大 10K 行 ArrayList 通过菜单选择更新。

手册notifyDataSetChange()

--- avg run-time: 4ms

默认免费notifyDataSetChange()

--- avg run-time: 0ms <--- you can't get faster than this.

除非您对自己的东西进行计时和基准测试,否则不要跑来创建自己的替代品。在必要时使用免费的东西。

【讨论】:

    【解决方案2】:

    我想你可以为你的 textView 设置一个标签作为获取更新的 url。而不是调用“notifyDataSetChanged()”,您可以尝试为该视图使用 findViewByTag(update URL) 和 setText,这样 textview 只会一遍又一遍地重绘而不是整个列表。将充分减少额外重绘的次数。只是一个想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 2011-06-08
      • 2015-09-06
      • 2015-01-22
      • 2023-03-14
      相关资源
      最近更新 更多