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

后端 未结 25 2064
执念已碎
执念已碎 2020-11-22 16:59

What I want to do: run a background thread which calculates ListView contents and update ListView partially, while results are calculated.

W

相关标签:
25条回答
  • 2020-11-22 17:42

    One cause for this crash is that ArrayList object cannot change completely. So, when I remove an item, I have to do this:

    mList.clear();
    mList.addAll(newDataList);
    

    This fixed the crash for me.

    0 讨论(0)
  • 2020-11-22 17:42

    I had a custom ListAdapter and was calling super.notifyDataSetChanged() at the beginning and not the end of the method

    @Override
    public void notifyDataSetChanged() {
        recalculate();
        super.notifyDataSetChanged();
    }
    
    0 讨论(0)
  • 2020-11-22 17:43

    I was also getting exact same error and using AsyncTask :

    `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. [in ListView(2131296334, class android.widget.ListView) with Adapter... etc
    

    I solved it by puttingadapter.notifyDataSetChanged(); at the bottom of my UI thread, that is my AsyncTask onPostExecute method. Like this :

     protected void onPostExecute(Void aVoid) {
    
     all my other stuff etc...
        all my other stuff etc...
    
               adapter.notifyDataSetChanged();
    
                    }
    
                });
            }
    

    Now my app works.

    EDIT : In fact, my app still crashed about every 1 in 10 times, giving the same error.

    Eventually I came across runOnUiThread on a previous post, which I thought could be useful. So I put it in my doInBackground method, like this :

    @Override
    protected Void doInBackground(Void... voids) {
    
        runOnUiThread(new Runnable() {
                          public void run() { etc... etc...
    

    And I removed the adapter.notifyDataSetChanged(); method. Now, my app never crashes.

    0 讨论(0)
  • 2020-11-22 17:44

    My issue was related to the use of a Filter together with the ListView.

    When setting or updating the underlying data model of the ListView, I was doing something like this:

    public void updateUnderlyingContacts(List<Contact> newContacts, String filter)
    {
        this.allContacts = newContacts;
        this.filteredContacts = newContacts;
        getFilter().filter(filter);
    }
    

    Calling filter() in the last line will (and must) cause notifyDataSetChanged() to be called in the Filter's publishResults() method. This may work okay sometimes, specially in my fast Nexus 5. But in reality, it's hiding a bug that you will notice with slower devices or in resource intensive conditions.

    The problem is that the filtering is done asynchronously, and thus between the end of the filter() statement and the call to publishResults(), both in the UI thread, some other UI thread code may execute and change the content of the adapter.

    The actual fix is easy, just call notifyDataSetChanged() also before requesting the filtering to be performed:

    public void updateUnderlyingContacts(List<Contact> newContacts, String filter)
    {
        this.allContacts = newContacts;
        this.filteredContacts = newContacts;
        notifyDataSetChanged(); // Fix
        getFilter().filter(filter);
    }
    
    0 讨论(0)
  • 2020-11-22 17:45

    I have a List if Feed objects. It's appended and truncated from none-UI thread. It works fine with adapter below. I call FeedAdapter.notifyDataSetChanged in UI thread anyway but little bit later. I do like this because my Feed objects stay in memory in Local Service even when UI is dead.

    public class FeedAdapter extends BaseAdapter {
        private int size = 0;
        private final List<Feed> objects;
    
        public FeedAdapter(Activity context, List<Feed> objects) {
            this.context = context;
            this.objects = objects;
            size = objects.size();
        }
    
        public View getView(int position, View convertView, ViewGroup parent) {
            ...
        }
    
        @Override
        public void notifyDataSetChanged() {
            size = objects.size();
    
            super.notifyDataSetChanged();
        }
    
        @Override
        public int getCount() {
            return size;
        }
    
        @Override
        public Object getItem(int position) {
            try {
                return objects.get(position);
            } catch (Error e) {
                return Feed.emptyFeed;
            }
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 17:45

    I had the same sittuation , I had many buttongroup insite my item on listview and I was changing some boolean values inside my item like holder.rbVar.setOnclik...

    my problem occured because I was calling a method inside getView(); and was saving an object inside sharepreference, so I had same error above

    How I solved it; I removed my method inside getView() to notifyDataSetInvalidated() and problem gone

       @Override
        public void notifyDataSetChanged() {
            saveCurrentTalebeOnShare(currentTalebe);
            super.notifyDataSetChanged();
        }
    
    0 讨论(0)
提交回复
热议问题