0

I am having trouble with updating my recyclerview with notify data set changed, since it hangs the ui for a couple of seconds upon called. After searching on the net, it was suggested to update the adapter on the background thread.

 private synchronized void updateAdapter() {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        public Void doInBackground(Void... params) {
            adapter.notifyDataSetChanged();
            return null;
        }
    };
    task.execute();
}

And upon running this line of code, the app crashed with the error,

"Only the original thread that created a view hierarchy can touch its views."

And upon searching further, it was suggested that the solution was to run on the ui thread.

runOnUiThread(new Runnable() {
 @Override
 public void run() {

}
});

Which brings me back to my initial problem. How should i handle this problem? Any help is appreciated. Thank you.

m.n Aswin
  • 119
  • 3
  • 7
  • You can't do `notifyDataSetChanged` in `doInBackground`, you have to do it inside `onProgressUpdate` or `onPostExecute . cause `doInBackground` just a callback fired in worker thread , and you would like to do `notifyDataSetChanged` which has to be in UI thread , so you can do `notifyDataSetChanged` in `onProgressUpdate` which work as handler to transfer your massage from worker thread to UI thread , or `onPostExecute which called in your UI thread after the worker thread finishes its work . – Ahmed Eltaher Mar 28 '17 at 13:19
  • 1
    But that hangs the ui. thats the initial problem. – m.n Aswin Mar 28 '17 at 14:56
  • 1
    This just proves that people mark question as duplicate without even reading it, so much for the community. – m.n Aswin Mar 28 '17 at 15:01

1 Answers1

1
 private synchronized void updateAdapter() {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        public Void doInBackground(Void... params) {
            adapter.notifyDataSetChanged();
            return null;
        }
    };
    task.execute();
}

Please study Asynctask doInBackground should not have any UI changes .In this case u are performing UI changes on seperate thread in asynctask . Put your notifydatasetchanged on onPostExecute as shown below( which works on Main Thread ). To add onPreExcute() and onPostExecute() are performed on Main UI and onBackground() on separate thread ( not Main UI ).

 private synchronized void updateAdapter() {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        public Void doInBackground(Void... params) {
           // query your db or perform long operations here 
           return null;
        }

        @Override
        onPostExecute(Void.. params){
             adapter.notifyDataSetChanged();
        }
    };
    task.execute();
}
DRY Believer
  • 1,001
  • 11
  • 20
  • onPostExeceute runs in the UI thread and it will hang the UI also – from56 Mar 28 '17 at 13:19
  • 1
    onRunning onPostExecute it hangs the ui which is the initial problem. – m.n Aswin Mar 28 '17 at 14:55
  • use notifychanged( int position ) this would help you update only specific cells.Please share your code because there shouldnt be too laggy until unless you are using a large number of different views – DRY Believer Mar 28 '17 at 15:04
  • I have the sam eproblem that you was facing. did you find the solution yet? – Sandip Savaliya Oct 05 '17 at 12:28
  • Hi @ShockWave... Please share the code... AsyncTask should suffice the problem ... – DRY Believer Oct 06 '17 at 07:59
  • hello @DRYBeliever , my code is too complex, as i am using volley to request data, it is already getting data from asynctask, and i amm getting all the data on my ui thread , now its a large amount of data, which is causing sticky UI. i tried many possibilities, and i have designed rest services, so for code, i have to send you many many files – Sandip Savaliya Oct 07 '17 at 05:07