Search code examples
androidandroid-listviewlistadaptercommonsware-cwac

java.lang.IllegalStateException in CommonsGuy EndlessAdapter


I was integrating commonsguy / cwac-endless EndlessAdapter in one of my application and it worked really great! Thanks to Sir CommonsWare :)

But I am getting java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification.

Note: This exception only occurs when I use endlessAdapter.setRunInBackground(false);, basically when I want my own implementation of AsyncTask to cache data (executing AsyncTask in cacheInBackground() method of EndlessAdapter class).

Steps to recreate this IllegalStateException:

Step 1) Run EndlessAdapterCustomTaskFragment example provided as demo for EndlessAdapter

Step 2) Scroll the ListView down so that progress view get's visible.

Step 3) Click the progress view. Now once the progress view is clicked while the data is loading, the application will get force closed with java.lang.IllegalStateException.

To overcome this issue, I override following methods of EndlessAdapter class and it really worked ;)

    @Override
    public boolean areAllItemsEnabled() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isEnabled(int position) {
        // TODO Auto-generated method stub
        return getItem(position) != null;
    }

I am very curious to know about the following:

1) Why EndlessAdapter implementation throws exception only when I want my own implementation of AsyncTask to cache data i.e endlessAdapter.setRunInBackground(false); BUT NOT when using endlessAdapter.setRunInBackground(true); with no custom implementation of AsyncTask

2) There is some relation between clicking ListView item and getCount() method of ListView because it generates Exception only when clicking ListView's progress indicator item.

Thanks in advance :)


Solution

  • Thank you for providing a reproducible test case for this problem. I made two changes to EndlessAdapter to attempt to address the issue, including incorporating a variation of the areAllItemsEnabled()/isEnabled() fix you outlined above. This has been committed and tagged as v1.2. If and when you move to v1.2 of the library, you will need to remove your own overrides of areAllItemsEnabled() and isEnabled().

    Why EndlessAdapter implementation throws exception only when I want my own implementation of AsyncTask to cache data i.e endlessAdapter.setRunInBackground(false); BUT NOT when using endlessAdapter.setRunInBackground(true); with no custom implementation of AsyncTask

    The exception is supplied to you via onException(), which you can override. This is to ensure that you get the exception on the main application thread, even when the exception might be caused in a background thread managed by EndlessAdapter.

    There is some relation between clicking ListView item and getCount() method of ListView because it generates Exception only when clicking ListView's progress indicator item.

    This is in the implementation of ListView.