Listview's ArrayAdapter notifydatasetchanged() very slow redraw
Asked Answered
L

2

6

I've a quite simple list with 3 textview fields on each row. We are updating their values every 2 seconds or so with data coming from a background webservice call ( AsyncTask )

We compare the coming values with the current ones, update them accordingly on the Adapter and finally calling notifyDataSetChanged() if needed

The thing is that the redraw gets really slow thus hanging the whole UI when we got more than 3 update rows at once. Of course we are using all ListView well-known optimizations such as the EfficientAdapter approach ( setTag() and holders ), and getViewTypecount()/getItemViewType() . We have also tried to optimize our interface as much as possible with layoutopt and trying to avoid wrap_content widths and heights to lighten things up .

We don't do expensive operations on our updates either, just standard stuff: changing TextView text, textcolor, and backgroundcolor values.

The only weird thing I can see is that getView() is called 3-4-5 times for each row, although I've read all those Romain's messages [1] telling that is nothing wrong with that

Any ideas or hints on how can we speed it up?

Thank you very much!

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

Lye answered 27/9, 2010 at 16:11 Comment(5)
It almost sounds like you're getting more updates than you are able to draw - have you tried decreasing the frequency of updates to 10 seconds to test this? If this helps you will need to find a solution for clearing the queue from the task with each update. 2 seconds is pretty often if you consider automatic garbage collection can take up to 1 second (hopefully not more) and other services can delay the update as well.Bozo
The calls are consecutive, so new ones are executed when the previous has finished.Lye
Garbage collector worst case takes over 200ms, that's nothing compared with the 1.5 - 2 s UI hang that the app experiences on each redraw. Refresh rate isn't affecting here, even if I raise it to 10s, after the call is fired the redraw will continue freezing for those 2 secondsLye
Have you tried doing some of this in AsyncTask?Piatt
How about using a profiler tool? What does DDMS say about the notifyDataSetChanged() timing? Oh, I just noticed the date on the question...have you solved it?Stinson
M
2

This is for those browsing from google thinking they need to rewrite their own data changed method. Based on my data, you don't need to for many cases.

notifyDataSetChanged() can be MUCH FASTER than your hand coded replacement and it all depends on your actual listview implementation.

Sample: A simple 3-line text-only listview with max 10K row ArrayList updated via menu selection.

Manual notifyDataSetChange()

--- avg run-time: 4ms

Default free notifyDataSetChange()

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

Don't run to create your own replacement unless you time and benchmark your stuff. Use the free stuff until necessary.

Manufactory answered 12/12, 2012 at 9:23 Comment(0)
P
0

I suppose you can set a tag to ur textView as the url where it will get the update from. And instead of calling "notifyDataSetChanged()", you can try using findViewByTag(update URL) and setText for that view, so the textview is only repainted not the entire list over and over again. Would sufficiently reduce the number of extra repaints. Just a thought.

Pyrimidine answered 6/10, 2011 at 8:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.