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.
Related
I am fetching contacts and this work is going fine. But I am try to also show the contacts in bunch of 50 which is fetched, i.e. user don't have to wait until all contacts has been fetched.
I try to with Asynctask , And Thread also but when I go to notify the list adapter then error has came.
"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. Make sure your
adapter calls notifyDataSetChanged() when its content changes"
Make sure you update the adapter from the onProgressUpdate() method of the AsyncTask. The onProgressUpdate() can be invoked by calling the publishProgress() from inside yourdoInBackground(). doInBackground() runs in the Background Thread, while onProgressUpdate() runs in your UI thread.
I use an AsyncTask and on doInBackground() I have a loop where I'm doing a lot of network calls. Each call gives me a new data object that I want to add it to my listView.
I know that I can call notifyDataSetChanged() on onPostExecute() and update my list with all my items but I'm wondering if its possible to somehow call notifyDataSetChanged() when I receive a new item and update my listView the same moment and not to have to wait until all the work on doInBackground finishes.
If there isn't a way I can do this with AsyncTask then whats the proper way to deal with something like that?
Thank you
Call publishProgress(...) from doInBackground(...) and override onProgressUpdate(...) in your AsyncTask and call notifyDataSetChanged() there.
Calling publishProgress(...) from doInBackground(...) instructs the AsyncTask to call it's onProgressUpdate(...) on the main UI thread, hence you can update the ListView from there.
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 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 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()