0

I would like to put a large number of add delete calculation work on the worker thread, notifyDataSetChanged work on the ui thread. On the basis of it to avoid the java.lang.IllegalStateException. Exception 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.

code shorthand such as:

new Thread(){
            @Override
            public void run() {
                for(int i=0; i<5000; i++){
                    mDatas.add(i);
                }
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.notifyDataSetChanged();
                    }
                });
            }
        }.start();

I am searching for a long time on net. But no use. Please help or try to give some ideas how to achieve this.

yulongzou
  • 3
  • 6

3 Answers3

0

You are adding items to ArrayList in non-UI thread and calling notifyDataSetChanged on the UI Thread

new Thread(){
            @Override
            public void run() {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        for(int i=0; i<5000; i++){
                            mDatas.add(i);
                        }
                        mAdapter.notifyDataSetChanged();
                    }
                });
            }
        }.start();
Sadiq Md Asif
  • 882
  • 6
  • 18
0

Try this

Check if mActivity is null or not before calling runOnUi thread

 new Thread(){
                @Override
                public void run() {
                    for(int i=0; i<5000; i++){
                        mDatas.add(i);
                    }
                  if(mActivity!=null){
                    mActivity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mAdapter.notifyDataSetChanged();
                        }
                    });
                   }
                }
        }.start();
Quick learner
  • 10,632
  • 4
  • 45
  • 55
0

There are two solutions to overcome with it.

1) Use AsyncTask and update your adapter in onPostExecute() method.

@override
protected void onPostExecute(String result) {
  mAdapter.notifyDataSetChanged();
}   

2) Use Handler with Thread to register message and in handleMessage() update your adapter.

    new Thread(){
        @Override
        public void run() {

                  handler.sendEmptyMessage(0);
                }
            });
        }
    }.start();

 Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            mAdapter.notifyDataSetChanged();
            return false;
        }
    });
Piyush
  • 18,895
  • 5
  • 32
  • 63