views:

92

answers:

3

I am using AsyncTask to perform some background calculations but I am unable to find a correct way to handle exceptions. Currently I am using the following code:

private class MyTask extends AsyncTask<String, Void, String>
{
    private int e = 0;

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            URL url = new URL("http://www.example.com/");
        }
        catch (MalformedURLException e)
        {
            e = 1;
        }

        // Other code here...

        return null;
    }

    @Override
    protected void onPostExecute(String result)
    {
        if (e == 1)
            Log.i("Some Tag", "An error occurred.");

        // Perform post processing here...
    }
}

I believe that the variable e maye be written/accessed by both the main and worker thread. As I know that onPostExecute() will only be run after doInBackround() has finished, can I omit any synchronization?

Is this bad code? Is there an agreed or correct way to handle exceptions in an AsyncTask?

+1  A: 

I've been doing that in my apps, I guess there is not a better way.

You can also read Mark Murphy answer about it.

Macarse
If it causes no problems then I am happy!
Leo
+1  A: 

This is guaranteed to work, even on SMP architecture. All the synchronization is done for you. It would however be better to use the return value to do this.

Romain Guy
In the actual code I am using a custom object as the return type which doesn't really lend itself to holding exception information. I assume I can't overload the `onPostExecute()` function very easily?
Leo
First of all, doInBackground must return an object of the same type as the parameter in onPostExecute(). Then you can just create a custom class to encapsulate the result + exception: class ResultHolder { Exception e; MyResult r; }
Romain Guy
A: 

I think your code would to the job but there is already some kind of error handling built into the AsyncTask class.

You can avoid to use an extra variable by using the cancel() method and its handler method onCancelled(). When you call cancel within the doInBackground() method the onCancelled method in the UI thread. Whether you call cancel(true) or cancel(false) depends on your needs.


private class MyTask extends AsyncTask<String, Void, String>
{    
    @Override
    protected NewsItem doInBackground(String... params)
    {
        try
        {
            URL url = new URL("http://www.example.com/");
        }
        catch (MalformedURLException e)
        {
            cancel(false/true);  
        }

        // Other code here...

        return null;
    }

    @Override
    protected void onPostExecute(String result)
    {              
        // Perform successful post processing here...
    }

   @Override
    protected void onCancelled() {
        super.onCancelled();
        // Perform error post processing here...
    }
}
Flo
This method only works if we have one type of exception. In my full code there are multiple things which can go wrong and they must be handled differently.
Leo
Why? You can add to the try-clause as much catch-class as u want. In each catch-statement u can call the cancel-Method. You also can catch(Exception e) which catches all types of Exceptions. Did I get u right, Leo? However, is it good practice to call cancel() when Exceptions are thrown or is there an other way of Exception handling implemented?
OneWorld