Android, ListView IllegalStateException: "The content of the adapter has changed but ListView did not receive a notification" Android, ListView IllegalStateException: "The content of the adapter has changed but ListView did not receive a notification" android android

Android, ListView IllegalStateException: "The content of the adapter has changed but ListView did not receive a notification"


I had the same issue.

I was adding items to my ArrayList outside the UI thread.

Solution: I have done both, adding the items and called notifyDataSetChanged() in the UI thread.


I had the same problem, but I fixed it using the method

requestLayout();

from the class ListView


This is a MultiThreading Issue and Using Properly Synchronized Blocks This can be prevented.Without putting extra things on UI Thread and causing loss of responsiveness of app.

I also faced the same. And as the most accepted answer suggests making change to adapter data from UI Thread can solve the issue. That will work but is a quick and easy solution but not the best one.

As you can see for a normal case. Updating data adapter from background thread and calling notifyDataSetChanged in UI thread works.

This illegalStateException arises when a ui thread is updating the view and another background thread changes the data again. That moment causes this issue.

So if you will synchronize all the code which is changing the adapter data and making notifydatasetchange call. This issue should be gone. As gone for me and i am still updating the data from background thread.

Here is my case specific code for others to refer.

My loader on the main screen loads the phone book contacts into my data sources in the background.

    @Override    public Void loadInBackground() {        Log.v(TAG, "Init loadings contacts");        synchronized (SingleTonProvider.getInstance()) {            PhoneBookManager.preparePhoneBookContacts(getContext());        }    }

This PhoneBookManager.getPhoneBookContacts reads contact from phonebook and fills them in the hashmaps. Which is directly usable for List Adapters to draw list.

There is a button on my screen. That opens a activity where these phone numbers are listed.If i directly setAdapter over the list before the previous thread finishes its work which is fast naviagtion case happens less often. It pops up the exception .Which is title of this SO question. So i have to do something like this in the second activity.

My loader in the second activity waits for first thread to complete. Till it shows a progress bar. Check the loadInBackground of both the loaders.

Then it creates the adapter and deliver it to the activity where on ui thread i call setAdapter.

That solved my issue.

This code is a snippet only. You need to change it to compile well for you.

@Overridepublic Loader<PhoneBookContactAdapter> onCreateLoader(int arg0, Bundle arg1) {    return new PhoneBookContactLoader(this);}@Overridepublic void onLoadFinished(Loader<PhoneBookContactAdapter> arg0, PhoneBookContactAdapter arg1) {    contactList.setAdapter(adapter = arg1);}/* * AsyncLoader to load phonebook and notify the list once done. */private static class PhoneBookContactLoader extends AsyncTaskLoader<PhoneBookContactAdapter> {    private PhoneBookContactAdapter adapter;    public PhoneBookContactLoader(Context context) {        super(context);    }    @Override    public PhoneBookContactAdapter loadInBackground() {        synchronized (SingleTonProvider.getInstance()) {            return adapter = new PhoneBookContactAdapter(getContext());            }    }}

Hope this helps