HiveBrain v1.2.0
Get Started
← Back to all entries
debugjavaMinor

AsyncTask which allows to handle exceptions on UI

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
exceptionsallowshandlewhichasynctask

Problem

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 {

public class ResultHolder {

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> _asyncTask = new AsyncTask>() {
@Override
protected ResultHolder doInBackground(Params... params) {

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

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

@Override
protected void onPostExecute(ResultHolder 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 resultHolder) {
}

Solution

First of all, a few notes:

-
ResultHolder can be a public static class.

-
This just feels wrong:

catch (Throwable e) {
    new ResultHolder(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 doInBackground(Params... params)  {
    try {
        return new ResultHolder(AsyncTaskWithThrowable.this.doInBackground(params));
    }
    catch (Exception e) {
        return new ResultHolder(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.

Code Snippets

catch (Throwable e) {
    new ResultHolder<Result>(e);
    return null;
}
public class AsyncException extends Exception {
    public AsyncException(String message, Throwable cause) {
        super(message, cause);
    }
}
public abstract Result doInBackground(Params ... params) throws AsyncException;

public Result getResult() throws AsyncException {

private ResultHolder(AsyncException throwable) {

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

Context

StackExchange Code Review Q#69405, answer score: 5

Revisions (0)

No revisions yet.