how to allow UI thread to wait for the background thread to finish?

1.7k Views Asked by At

I can use AsnycTask get() method to wait for the background task to be completed, But how do I do it if I'm using CursorLoader and ContentProvider with LoaderManager Callback?

Is it also possible to prevent the UI thread from waiting for the data returned in the background thread?

4

There are 4 best solutions below

1
On

You can easily pass your interface to get call back of Asynctask .This is right way to get solution of your problem

0
On

Show ProgressDialog to wait untill response is not receive. if your response is receiving from same class or activity then do not use interface call back, if response is receiving from other activity of class then use interface call back

0
On

Wait on UIThread is not recommended it makes app looks like laggy or stucked. blundell made good point in the edit.

0
On

I have exactly the same situation in one of my current project where i have to request the list of contacts using the content provider and cursor loaders to display them later on a listview.

So here is what you should do:

  • Make an Async call to the content provider from whithin your activity/fragment using the async task as a static inner class.
  • Inside the AsyncTask doInBackground() method you place your function to retrieve the cursor and process your data there so you end up with returning a List<Object> Object is the returned Model (Contact) in my case.
  • Inside the AsyncTask's onPostExecute() method you just pass the retreived data list to whatever View you are working with (again in my case it's a List<Contact> and there where your mainThread is receiving data and only there it has to process the data when it's ready.

AsyncTask make your life much easier as they have a string structure to handle passing data from a MainThread to a background separate Thread and then ship back the data from the background Thread to the MainThread.

In terms of code your code should look like :

public class MainActivity extends Activity {
    private AsyncTask mTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //
        ...... 
        //Call the AsyncTask and pass your Data
        mTask = new Task(this);
        mTask.execute();
    }

    private static class Task extends AsyncTask<Void, Void, List<Object> {
        private WeakReference<Contex> mContextRef;
        public Task(Context context) {
            mContextRef = new WeakReference<>(context);
            //later when you need your context just use the 'get()' method. like : mContextRef.get() (this will return a Context Object.
        }

        @Override
        protected void onPreExecute() {
            // show progress Dialog
           //this method is processed in the MainThread, though it can prepare data from the background thread.
        }

        @Override
        protected List<Object> doInBackground(Void ... params) {
            List<Object> mList = new ArrayList<>();
            //Call your content provider here and gather the cursor and process your data..
           //return the list of object your want to show on the MainThread.
           return mList;
        }

        @Override
        protected Void onPostExecute(List<Object> list) {
            if(list.size() > 0) {
            //do your stuff : i.e populate a listView
            }
        }
    }
}