0

When using AsyncTask and doing doInBackground() I sometimes get a result that stats that I don't want to go on to onPostExecute(). I tried to use cancel(true); but it still goes into onPostExecute()

Thats my code:

@Override
    protected LiveMatchDetails doInBackground(Void... params) {
        try {
            events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_NETWORK);
        } catch (Exception e) {
            Log.e(TAG, "Error loading events", e);
            try {
                events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_CACHE);
            } catch (Exception e1) {
                e1.printStackTrace();
                cancel(true);
                onProgressUpdate();
            }
        }
        return events;
    }

Is there a way to prevent the call to onPostExecute() from within the doInBAckground()?

roiberg
  • 13,629
  • 12
  • 60
  • 91

3 Answers3

2

No there is no way to avoid onPostExecute() but you can skip your onPostExecute() code using the result part like this :-

take a flag or any var.

int flag_response=0;
@Override
    protected LiveMatchDetails doInBackground(Void... params) {

        try {

            events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_NETWORK);
 flag_response=1;
        } catch (Exception e) {
            Log.e(TAG, "Error loading events", e);
            try {
                events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_CACHE);
            } catch (Exception e1) {
                e1.printStackTrace();
                cancel(true);
     flag_response=0;
                onProgressUpdate();
            }
        }
        return events;
    }



 @Override
   protected void onPostExecute(String result) {
    if(flag_response==1)
    // execute your code
    else 
    //skip
    }
Praveen Sharma
  • 4,326
  • 5
  • 25
  • 45
  • So, what does cancel(true) does? – roiberg Dec 12 '13 at 13:09
  • calling "Cancel" sends and interrupt signal to the thread. If your process can be interrupted, it will stop blocking and continue to execute. You then have to call isCancelled() in doInBackground() and return from the method if isCancelled() is true. After which, onCanceled() and onPostExecute() will be called and the thread will die on it's own like norma – Praveen Sharma Dec 12 '13 at 13:10
  • Sincerely I don't agree with your answer: why allocate another variable if you can simply check if "events" is null? If exception is launched, then catch it and set events = null; then in onPostExecute() do the rest of the work. – JJ86 Dec 12 '13 at 13:10
  • you can use event if your event is not using anywhere or its dependent to this async task only – Praveen Sharma Dec 12 '13 at 13:11
1

If exception occur, then put only events = null; on catch block and in onPostExecute() do this:

protected void onPostExecute(YourObject result) {
    if (result != null) {
        // do whatever you want
    }
}

By the way, if you look at this link:

A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

EDIT

If an exception is throwed (during whatever happens on doInBackground method), your code will go directly to onPostExecute. If you call cancel(true), then you have to implement onCancelled(Object) and do whatever you want.

IMHO you have to make a difference between unexpected result and cancelling your task:

  • first one is quickly managed by catch block and let you know what happened during execution;
  • second one is useful only if you want to interrupt your task, for example you press the back button.

That's how i use AsyncTask.

JJ86
  • 5,055
  • 2
  • 35
  • 64
  • From you attached link I can see that cancel(true) should do the job... Am I understanding it wrong? I will use your answer if not. – roiberg Dec 12 '13 at 13:07
  • @roiberg if you use cancel(true), then you have to override also onCancelled(Object) method. – JJ86 Dec 12 '13 at 13:09
  • If i will override onCancelled(Object) than cancel will cause it to go to onCancelled instead of onPostExecute()? – roiberg Dec 12 '13 at 13:11
  • cancel() will not do the job. You can call isCanceled() and it will return what you set in in cancel() – Martin Vandzura Dec 12 '13 at 13:17
  • After testing I see that in Android 4.x calling cancel does the job and avoid calling onPostExecute. but in Android 2.x it's not... – roiberg Dec 12 '13 at 13:33
  • 1
    @roiberg quick searched on Big G: http://stackoverflow.com/questions/11165860/asynctask-oncancelled-not-being-called-after-canceltrue and http://stackoverflow.com/questions/3334858/onpostexecute-on-cancelled-asynctask – JJ86 Dec 12 '13 at 13:37
1

Just add a private Exception member to your flavour of AsyncTask.

private Exception exc = null;

When you catch an exception assign the caught exception to your private exc value.

catch (Exception e1) {
                exc = e1;
                 // ... other handling code.
            }

In onPostExecute check if exc is null. If it's null (no exception) execute your code. Else just do nothing or make an error message. EDIT: If you want to use cancel() just call if(isCancelled()) to check if it's canceled.

VM4
  • 6,321
  • 5
  • 37
  • 51