AsyncTask: where does the return value of doInBackground() go?

When calling AsyncTask<Integer,Integer,Boolean>, where is the return value of:

protected Boolean doInBackground(Integer... params)?

Usually we start AsyncTask with new AsyncTaskClassName().execute(param1,param2......); but it doesn't appear to return a value.

Where can the return value of doInBackground() be found?


Solution 1:

The value is then available in onPostExecute which you may want to override in order to work with the result.

Here is example code snippet from Google's docs:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
      protected Long doInBackground(URL... urls) {
          int count = urls.length;
          long totalSize = 0;
          for (int i = 0; i < count; i++) {
              totalSize += Downloader.downloadFile(urls[i]);
              publishProgress((int) ((i / (float) count) * 100));
          }
          return totalSize;
      }

      protected void onProgressUpdate(Integer... progress) {
          setProgressPercent(progress[0]);
      }

      protected void onPostExecute(Long result) {
          showDialog("Downloaded " + result + " bytes");
      }
 }

Solution 2:

You can retreive the return value of protected Boolean doInBackground() by calling the get() method of AsyncTask class :

AsyncTaskClassName task = new AsyncTaskClassName();
bool result = task.execute(param1,param2......).get(); 

But be careful of the responsiveness of the UI, because get() waits for the computation to complete and will block the UI thread.
If you are using an inner class, it's better to do the job into the onPostExecute(Boolean result) method.

If you just want to update the UI, AsyncTask offers you two posibilites :

  • To update the UI in parallel with the task executed in doInBackground() (e.g. to update a ProgressBar), you'll have to call publishProgress() inside the doInBackground() method. Then you have to update the UI in the onProgressUpdate() method.
  • To update the UI when the task is done, you have to do it in the onPostExecute() method.
    /** This method runs on a background thread (not on the UI thread) */
    @Override
    protected String doInBackground(String... params) {
        for (int progressValue = 0; progressValue  < 100; progressValue++) {
            publishProgress(progressValue);
        }
    }
    
    /** This method runs on the UI thread */
    @Override
    protected void onProgressUpdate(Integer... progressValue) {
        // TODO Update your ProgressBar here
    }
    
    /**
     * Called after doInBackground() method
     * This method runs on the UI thread
     */
    @Override
    protected void onPostExecute(Boolean result) {
       // TODO Update the UI thread with the final result
    }
    

    This way you don't have to care about responsiveness problems.