Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch Exception of AsyncTask. Need Thinking

I want to catch exception of a thread in doInBackground and print the error message in onPostExcecute. The problem is I don't have the Throwable object in onPostExecute. How to catch Exception in non-UI thread and print the error message in UI-thread?

public class TestTask extends AsyncTask<Void, Void, List<String>> {

    @Override
    protected List<String> doInBackground(final Void... params) {
        try {
            ...
            return listOfString;
        } catch(SomeCustomException e) {
            ...
            return null;
        }       
    }

    @Override
    protected void onPostExecute(final List<String> result) {
        if(result == null) {
            // print the error of the Throwable "e".
            // The problem is I don't have the Throwable object here! So I can't check the type of exception.
        }

    }
}

Update after Arun's answer:

This is my AsyncTask wrapper class. It intends to do handling Exception in doInBackground but I can't find a good solution to do it.

public abstract class AbstractWorkerTask<Params, Progress, Result>
extends AsyncTask<Params, Progress, Result>
implements Workable {
    protected OnPreExecuteListener onPreExecuteListener;
    protected OnPostExecuteListener<Result> onPostExecuteListener;
    protected ExceptionHappenedListener exceptionHappendedListener;
    private boolean working;

    @Override
    protected void onPreExecute() {
        if (onPreExecuteListener != null) {
            onPreExecuteListener.onPreExecute();
        }
        working = true;
    }

    @Override
    protected void onPostExecute(final Result result) {
        working = false;
        if(/* .........*/ ) {
            exceptionHappendedListener.exceptionHappended(e);
        }
        if (onPostExecuteListener != null) {
            onPostExecuteListener.onPostExecute(result);
        }
    }

    @Override
    public boolean isWorking() {
        return working;
    }

    public void setOnPreExecuteListener(final OnPreExecuteListener onPreExecuteListener) {
        this.onPreExecuteListener = onPreExecuteListener;
    }

    public void setOnPostExecuteListener(final OnPostExecuteListener<Result> onPostExecuteListener) {
        this.onPostExecuteListener = onPostExecuteListener;
    }

    public void setExceptionHappendedListener(final ExceptionHappenedListener exceptionHappendedListener) {
        this.exceptionHappendedListener = exceptionHappendedListener;
    }

    public interface OnPreExecuteListener {
        void onPreExecute();
    }

    public interface OnPostExecuteListener<Result> {
        void onPostExecute(final Result result);
    }

    public interface ExceptionHappenedListener {
        void exceptionHappended(Exception e);
    }
}
like image 936
emeraldhieu Avatar asked Jun 08 '12 07:06

emeraldhieu


People also ask

What is the use of AsyncTask class?

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

Why we use AsyncTask in Android?

Android AsyncTask is an abstract class provided by Android which gives us the liberty to perform heavy tasks in the background and keep the UI thread light thus making the application more responsive. Android application runs on a single thread when launched.

How to use AsyncTask?

Example Code syntax for Android AsyncTask:The AsyncTask instance must be created and invoked in the UI thread. AsyncTask can be called only once. Executing it again will throw an exception. You can change the return parameter type as well as request parameter type according to your requirement.


1 Answers

Change the return type of doInBackground() to Object and when you receive the result in onPostExecute(Object result) use the instanceOf operator to check if the returned result is an Exception or the List<String>.

Edit

Since the result can either be an Exception or else the proper List, you can use the following:

protected void onPostExecute(final Object result) {
    working = false;
    if(result instanceof SomeCustomException) {
        exceptionHappendedListener.exceptionHappended(result);
    }
    else{
        if (onPostExecuteListener != null) {
            onPostExecuteListener.onPostExecute(result);
        }
    }
}

Also change the following statement:

public abstract class AbstractWorkerTask<Params, Progress, Object> extends AsyncTask<Params, Progress, Object>
like image 150
Arun George Avatar answered Sep 20 '22 13:09

Arun George