AndroidEnthusiast
AndroidEnthusiast

Reputation: 6657

Content Adapter and Async Callbacks

I'm using a third party cloud service (Kinvey) to fetch data for my app. All Kinvey methods that service are wrapped in async classes. I'm currently getting an error log below and I understand why I am getting it. I just don't know how to resolve the problem.

Error :

03-12 13:41:03.449: E/AndroidRuntime(18375): FATAL EXCEPTION: main

03-12 13:41:03.449: E/AndroidRuntime(18375): 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(2130968661, class android.widget.ListView) with Adapter(class com.example.chartviewer.LazyAdapter)]


Here is the segment of my code where I notify my adapter after deleting content within an async method :

mKinveyClient.appData("artistdata", ArtistData.class).delete(artistID, new KinveyDeleteCallback() {

       @Override
        public void onSuccess(KinveyDeleteResponse result) {

              Log.e("DELEET", "Data Deleted sucessfully");
              Toast.makeText(getBaseContext(),
                      "Artist Deleted", Toast.LENGTH_SHORT).show();

                //refreshes list 
            adapter.notifyDataSetChanged(); 

           //displays dialog box if no artists left 
           displayNoArtist();

        }
        @Override
        public void onFailure(Throwable error) {
             Log.e("DELETE", "AppData.delete Failure", error);
        }
    });


Updating the adapter :

mKinveyClient.appData("artistdata", ArtistData.class).get(myQuery, new 
KinveyListCallback<ArtistData>() {
         @Override
         public void onSuccess(ArtistData[] result) {

              Log.e("FETCHING", "Data fetched sucessfully");
             for (ArtistData data : result) {


                 String name= data.getArtistname();
                 String imageurl = data.getArtisturl();

                 String id = data.getArtistid();

                 artistIds.add(id);

                  HashMap<String, String> hashMap = new HashMap<String, String>();

                  hashMap.put(TAG_NAME, name);
                  hashMap.put(TAG_IMAGEURL, imageurl);

                  addMyArtists(hashMap);


             }

             displayData();

         }

         @Override
         public void onFailure(Throwable error) {

             Log.e("FETCHING", "AppData.get by Query Failure", error);

         }
     });


Adaptor creator code :

      list = (ListView)findViewById(R.id.artistlist);
      adapter = new LazyAdapter(MyArtistsActivity.this,"artists", artistItemList);
      list.setAdapter(adapter);
      registerForContextMenu(list);

Upvotes: 1

Views: 528

Answers (1)

mjsalinger
mjsalinger

Reputation: 660

Disclaimer: I am a member of Kinvey's engineering team.

The issue is that you are deleting from the artistItemList prior to deleting from the Kinvey backend, and then not calling adapter.notifyDatasetChanged until the callback. This results in the lag you noticed where the underlying dataset has changed while waiting for the callback from the backend Kinvey delete call. You need to group both of these calls together, and do it in one of two ways:

  1. Make the artistID that you pass to the delete method final, and in onSuccess, remove the item from artistItemList before calling adapter.notifyDatasetChanged.
  2. Call adapter.notifyDatasetChanged before calling the kinveyClient.appData().delete() method, immediately after removing the item from artistItemList. This option may cause issues if the delete fails on the Kinvey back-end.

Upvotes: 2

Related Questions