Edward van Raak
Edward van Raak

Reputation: 4910

Android: Get the return value from an AsyncTask without blocking the UI thread

Inside the onCreate of an Activity I do the following:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);         
    AsyncTask<String, Integer, String[]> asynctask = new DownloadFilesTask(this.getActivity()).execute(url);
    String[] values = null;         
    try {
        values = asynctask.get();
    } catch (InterruptedException e) {          
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    Log.d("AsyncTask", "DONE!");        
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
            android.R.layout.simple_list_item_1, values);

    setListAdapter(adapter);
}

This works but I am blocking the UI thread with asynctask.get(); which stops me from showing any new UI elements like a dialog during the background task that it performs.

So my question: How do I get the result value from my AsyncTask without blocking the UI thread given this code?

Upvotes: 1

Views: 1392

Answers (3)

Eng.Fouad
Eng.Fouad

Reputation: 117607

get() is designed to be called from inside onPostExecute(Result result). Basically the latter is executed on the UI thread just after doInBackground() is finished or throws exception.

For Example:

class DownloadFilesTask extends AsyncTask<Params, Progress, Result>
{
    @Override
    public Result doInBackground(Params... params)
    {
        // ...
    }

    @Override
    public void onPostExecute(Result result)
    {
        try
        {
            Result result = get();

            // we are fine here, do something with the result
        }
        catch(CancellationException e){/* if cancel() is called on this instance */}
        catch(ExecutionException e){/* if doInBackground() throws some exception */}
        catch(InterruptedException e){/* If the current thread was interrupted while waiting */}
    }
}


EDIT: I must be confused with SwingWorker :\

After doInBackground() is finished, onPostExecute(Result result) is executed on the UI thread with having the result passed from doInBackground() as a method parameter.

class DownloadFilesTask extends AsyncTask<Params, Progress, Result>
{
    @Override
    public Result doInBackground(Params... params)
    {
        // ...
    }

    @Override
    public void onPostExecute(Result result)
    {
        // do something with the result
    }
}

Upvotes: 1

yahya
yahya

Reputation: 4860

1- Could you post also DownloadFilesTask?

2- When asyncTask executes, it's not gonna loaded or whatever you're doing, that's not gonna happen immediately, right? So just after you call asynctask you may not be able to get results from it... So i would suggest you to use onPostExecute method of asyncTask

Upvotes: 0

Anton-M
Anton-M

Reputation: 1111

move this to onPostExecute:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
        android.R.layout.simple_list_item_1, values);

setListAdapter(adapter);

Upvotes: 5

Related Questions