i have the following problem. I fill a ListView with a custom ArrayAdapter with data from a BD. However, in background, i'm updating those datas from the info provided by an API, so the idea is when the update finish, the adapter shows the updated data instead its "old version".
The problem is that when i do that, i notice a lag while the adapter is updating itself. Is the any efficient solution to avoid this?
Thanks
You can call notifyDataSetChanged() on your ListAdapter to cause it to update to the current data immediately. Note that you should do this from the main UI thread, using a Handler or Activity.runOnUIThread()
Related
After I've downloaded a list of objects from a rest service, obviously in an AsyncTask, I set them into a custom BaseAdapter. When I call again the service to load more data and add them to the List of object, and call the notifyDataSetChanged() the ListView block for a sec or two.
I've tried to move the add and notify into another AsyncTask but since I'm modifying the UI this raised an exception.
I've tried also to change the addAll with a loop where I add an item at time and call the notifyDataSetChanged() everytime but with no success.
Which is the best practice in this case?
Sorry for no code but I'm from my phone, this thing really puzzles me.
How many times you are call notifyDataSetChanged()? You need to call it once, after you add all data. If you show code of your AsyncTask class and how do you use it, I will tell more.
I have an array adapter which is used in my listview. The adapter is periodically updated by fetching or removing contents from a server. I have used a scheduledthreadpoolexecutor to periodically update the adapter and then use adapter.notifydatasetchange();
The list view gets refreshed and removes any items etc, but for example if two items where removed from the list when I scroll the listview on android and get close to the end of the listview the application crashes. I guess something does not get updated in the listview and it things that the size of the list is the initial size.
Do you have something to recommend?
Regards,
Aris
Hi all,
I actually found a solution to my problem and forgot to check here for any replies.
Thank you all for your suggestions.
Basically scheduledthreadpoolexecutor called a runnable (lets call it updateRunnable) to do the updates.
What I did was the following:
In the updateRunnable, when it gets the new data and stores them in the array adapter, it then calls another runnable (lets call it updateListView) using runOnUiThread and in updateListView I set the adapter of the listview.
This solved my problem
If your data is at all database-like, which I assume, given your use of a ListView, then you'll want to refactor your background service into a model that uses a ContentProvider and SyncAdapter to stay in sync with the server, and then automatically notify the ListView through binding it with a CursorAdapter which uses its implementation of ContentObserver to automatically update the list when the underlying DB changes.
Why does ContentResolver.requestSync not trigger a sync? tells you how to set up the ContentProvider.
How to handle REST calls, data persistence, syncing and observing ContentProvider tells you a little more about how list update notification operates once the ContentProvider is syncing.
It's a lot of infrastructure work to get set up, but once you do, there's so much that's wonderfully automatic about the SyncAdapter model.
I had a similar problem once. Since the ListView keeps updating you can
1) display the Listview just as the activity starts in OnCreate, and
2) call this SAME activity so as to display refreshed data in the listview.
but after calling the same activity again, finish() the current instance first immediately since you can get multiple instances of it one over the other.
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.
my list-view contains huge data`s
am calling the bellow code using handler when the data is changed in the list
listviewAdapter.notifyDataSetChanged();
but i get the same error some times and not every time i load it
thanks in advance
the question is not where the adapter update, it should be: the time the adapter update.
it look likes: your data bind to the adapter has be changed, and the ui have be updated, so this time, the system find the data changed but can't invoke the notifyDataSetChanged.
so, suggestion when you change the adapter's data, invoke notifyDataSetChanged immediately,
or
dont directed change the adapter's data in your thread, you should send the data to the hanlder, and in the handler using the data to replace or change the adapter's data and notifyDataSetChanged.
so anyway, suggestion get the data can run in background thread, and update the data , notifyDataSetChanged used in ui thread.
the error is quite clear. You have not to call listviewAdapter.notifyDataSetChanged(); from a thread different of the UI thread.
Modify the arguments of the adapter in runOnUIThread() or use a handler to notify the adapter that the dataset has changed.
I am looking to refresh a ListView without reloading the page. More precisely I have a service that is sending data for a ListView in an Activity, however the Activity loads long before the Service can get the data. So I need to be able to load/reload the ListView after the Activity has already loaded.
I found that notifyDataSetChanged only works if you use the add, insert, remove, and clear functions on the Adapter, so I ended up doing it the following way in a similar implementation:
An AsyncTask fetches all the data in doInBackground. Then, when finished I set the list adapter for the first time in onPostExecute. To let the user know that something is loading, I just put a TextView on top of the Listview and set its text to "Loading.." in onPreExecute and then make it invisible in onPostExecute when the data is ready.
If you need to refresh the data, you just execute the AsyncTask again.
I like this way because you are only setting the ArrayAdapter once (i.e. when you finally have all the data). Here is more on AsyncTask in case you need it. The docs have some nice example code.
Call notifyDataSetChanged() on the ListView's Adapter whenever you want to refresh it.
I would say to use IntentService instead of Service. By, using IntentService you will be able to send data to the background Service and also receive the updated data while firing a BroadCastReceiver to update your UI. Here is a complete example how you can achieve your task using an IntentService.
I'm using a SimpleAdapter to populate a ListActivity. From the Google I/O video 'the world of ListView' it's made clear that the notifyDataSetChanged() method (for SimpleAdapter) MUST be called from the UI thread. But as regards updating the ArrayList in my ListActivity can that be safely done from any other thread?
Currently I do use a non-ui thread to update data in my ArrayList and then call notifyDataSetChanged() from the UI thread. This works fine and I can also dynamically update the SimpleAdapter too. However there is a certain aspect of my app that can cause it to crash and it happens when my ListActivity is in focus. I'm just currently exploring possible causes of the exception and it was something mentioned in the Google I/O video that left me unsure as to whether I can safely update my ArrayList from another thread.
According to the source code, adapted does not do any kind of synchronization on the underlying data list, so I assume it should only be changed from the UI thread.