AsyncTask which allows to handle exceptions on UI The AsyncTask available in android, gives you the result from doInBackground on the UI thread so that you can update UI according to the result, but exceptions need to be handled inside doInBackground function.

So following is my generic solution to the problem, the main objective here is to allow user to handle exceptions exactly the same way he does when working with synchronous code.

public abstract class AsyncTaskWithThrowable&lt;Params, Progress, Result&gt;  {

    public class ResultHolder&lt;Result&gt; {

        private ResultHolder(Result result) {
            _result = result;
        }

        private ResultHolder(Throwable throwable) {
            _throwable = throwable;
        }

        private Throwable _throwable = null;

        private Result _result;

        public Result getResult() throws Throwable{
            if (_throwable != null) {
                throw _throwable;
            }

            return _result;
        }
    }

    private AsyncTask&lt;Params, Progress, ResultHolder&lt;Result&gt;&gt; _asyncTask = new AsyncTask&lt;Params, Progress, ResultHolder&lt;Result&gt;&gt;() {
        @Override
        protected ResultHolder&lt;Result&gt; doInBackground(Params... params)  {

            try {
                return new ResultHolder&lt;Result&gt;(AsyncTaskWithThrowable.this.doInBackground(params));
            }
            catch (Throwable e) {
                new ResultHolder&lt;Result&gt;(e);
                return null;
            }
        }

        @Override
        protected void onPreExecute() {
            AsyncTaskWithThrowable.this.onPreExecute();
        }

        @Override
        protected void onPostExecute(ResultHolder&lt;Result&gt; result) {
            AsyncTaskWithThrowable.this.onPostExecute(result);
        }

        @Override
        protected void onProgressUpdate(Progress... values) {
            AsyncTaskWithThrowable.this.onProgressUpdate(values);
        }
    };

    public abstract Result doInBackground(Params ... params) throws Throwable;

    protected void onPreExecute() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    protected void onPostExecute(ResultHolder&lt;Result&gt; resultHolder) {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    protected void onProgressUpdate(Progress... values) {
    }

    public final AsyncTaskWithThrowable&lt;Params, Progress, Result&gt; execute(Params... params) {
         _asyncTask.execute(params);
        return this;
    }
}


And this is how you use it.

new AsyncTaskWithThrowable&lt;Boolean, Void, String&gt;(){

    @Override
    protected String doInBackground(Boolean ...params) {
        if (!params[0]) {
            throw new InvalidParameterException();
        }
        return "result";
    }

    @Override
    protected void onPostExecute(ResultHolder&lt;String&gt; resultHolder) {
        try{
            String result = resultHolder.getResult();
            // Change UI
        }
        catch (InvalidParameterException e) {
            // Change UI
        }
        catch (Throwable e) {
            // I don't like this catch block, but i couldn't find a way to avoid it.
        }
    }
}.execute(false);


The problem I see with it is user is forced to handle Throwable (also doInBackground can throw anything), but I cannot use typed parameter for exception here, as Java doesn't allow to catch it.
First of all, a few notes:


ResultHolder&lt;Result&gt; can be a public static class.
This just feels wrong:

catch (Throwable e) {
    new ResultHolder&lt;Result&gt;(e);
    return null;
}


You should probably return that ResultHolder, shouldn't you?
Avoid @SuppressWarnings({"UnusedDeclaration"}). If you have a warning there, then find out why it is there and solve it. Don't mark it as ignored. Sometimes, marking warnings ignored this way is fine, I would never do it with an UnusedDeclaration warning though.


As for your question about the Throwable, you are right that it is not a good idea to use that there. You can solve this by wrapping the exception in another.

public class AsyncException extends Exception {
    public AsyncException(String message, Throwable cause) {
        super(message, cause);
    }
}


And then:

public abstract Result doInBackground(Params ... params) throws AsyncException;

public Result getResult() throws AsyncException {

private ResultHolder(AsyncException throwable) {

@Override
protected ResultHolder&lt;Result&gt; doInBackground(Params... params)  {
    try {
        return new ResultHolder&lt;Result&gt;(AsyncTaskWithThrowable.this.doInBackground(params));
    }
    catch (Exception e) {
        return new ResultHolder&lt;Result&gt;(new AsyncException("Error while performing doInBackground", e));
    }
}


Problem solved! Note that I changed to catching Exception instead of Throwable as Errors (throwables that are not exceptions) shouldn't really be caught, they are much more serious so they are meant to crash everything.