I am working with adapters
in Android and in rare scenario's the app is crashing while setting data for ListView
...Please Help out. The Exception is as follows
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.
Make sure your adapter calls notifyDataSetChanged() when its content changes.
[in ListView(2131558745, class android.widget.ListView)
with Adapter(class com.adapters.CustomToBeSyncAdapter)
Here is My code snippet
private class ImportAsyncTask extends AsyncTask<Void, Integer, Integer> {
@Override
protected Integer doInBackground(Void... params) {
Realm realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
RealmResults<AssetsActivitiesRealm> mResultsActivities = realm.where(AssetsActivitiesRealm.class).findAll();
for (int i = 0; i < mResultsActivities.size(); i++) {
AssetsActivitiesRealm mAssetsActivitiePj = mResultsActivities.get(i);
SyncPojoList.add(new SyncPojo(mAssetsActivitiePj.getBatch(), mAssetsActivitiePj.getItemCode()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
realm.close();
return 1;
}
@Override
protected void onPreExecute() {
showLoading();
}
@Override
protected void onPostExecute(Integer sum) {
try {
cancelLoading();
displayListView();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void notifyAdapter() {
getActivity().runOnUiThread(new Runnable() {
public void run() {
listViewSync.setAdapter(null);
if (mdataAdapter != null) {
mdataAdapter.notifyDataSetChanged();
listViewSync.requestLayout();
}
}
});
}
private void displayListView() {
mdataAdapter = new CustomToBeSyncAdapter(getActivity(),
R.layout.custom_tobesync_row, SyncPojoList);
notifyAdapter();
listViewSync.setAdapter(mdataAdapter);
listViewSync.invalidate();
}
As you're adding objects inside the AsyncTask#doInBackground()
you're still changing the model of the ListView
's adapter from a background thread.
Try using the AsyncTask#publishProgress(Progress...)
inside your for-loop
and then override AsyncTask#onProgressUpdate(Progress...)
where Progress
is your model.
So your for-loop
could look something like this:
RealmResults<AssetsActivitiesRealm> mResultsActivities = realm.where(AssetsActivitiesRealm.class).findAll();
for (int i = 0; i < mResultsActivities.size(); i++) {
AssetsActivitiesRealm mAssetsActivitiePj = mResultsActivities.get(i);
publishProgress(new SyncPojo(mAssetsActivitiePj.getBatch(), mAssetsActivitiePj.getItemCode());
}
And your onProgressUpdate
could look like this:
public void onProgressUpdate(SyncPojo progress) {
SyncPojoList.add(progress);
mdataAdapter.notifyDataSetChanged(); // Notifying changes to the adapter here.
}
It's not clear why you need to run all of this inside an AsyncTask
and Realm actually advertises that you don't really need to run queries inside a background thread, as their querying is so fast (they're using lazy-loading when getting data) that it should affect the UI thread in most cases - especially when you don't have any "special" queries at all.
On another note, you don't need to create a Realm.Transaction
to query the data. Transactions are only used to ensure correctness when changing data.
You could definitely simplify your code a lot:
requestLayout
on your ListView
after calling notifyDatasetChanged
which is probably useless. try-catch
with Exception
for what reason? You should handle the code before it can lead to an exception instead of just adding a try-catch
around the error prone code. AsyncTask
returns a meaningless integer instead of actually returning the result for instance. ListView
to be updated, so no need to call your notifyAdapter
. notifyAdapter
method is doing a lot of things, that it doesn't need to do - setting the adapter to null
for instance. Hope this helps, else I'll be happy to elaborate on any areas.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.