Nikoi
Nikoi

Reputation: 389

AsyncTask never executes onPostExecute

I am trying to execute the following AsyncTask :

private class TimeUpdateTask extends AsyncTask<List<mObject>, Integer, Void> {

        @Override
        protected Void doInBackground(List<mObject>... params) {
            mObject o;
            int i;
            int numChecked = 0;

            List<mObject> mObjects = params[0];
            while(true)
            {   
                if (isCancelled())
                {
                    Log.w("TAG", "task interrumped");
                    return null;
                }

                    for (i=0 ; i < mObjects.size() ; i++)
                    {
                        o = mObjects.get(i);
                        if (!o.isChecked())
                        {
                            o.calculateProgress();
                            if (o.isChecked())
                            {
                                numChecked++;
                            }
                        }
                    }
                publishProgress(numChecked);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }

            }
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void onProgressUpdate(Integer... param){
            int progressCompleted = param[0];

            ((ArrayAdapter<mObject>) EventListView.this.EventView.getAdapter()).notifyDataSetChanged();

            mMain.setProgressBarCompleted(progressCompleted);
        }

        /*This should execute*/
        @Override
        protected void onPostExecute(Void result) {
            Log.d("TAG","End onPostExecute");
         }

    }

So when I call cancel(false) on this task, onPostExecute should be executed but it never is.

Is there any problem in the code or something else? I have looked at a lot of answers in SO and it seems that having #5 AsyncTask hanging around is normal, even if you are using only one (as in my case) at the moment.

Upvotes: 3

Views: 1717

Answers (3)

james
james

Reputation: 26271

There is 1 large piece missing here that you must learn about.

from the developer docs (see bold text below): http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)

Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.

Calling this method will result in onCancelled(Object) being invoked on the UI thread after doInBackground(Object[]) returns. Calling this method guarantees that onPostExecute(Object) is never invoked. After invoking this method, you should check the value returned by isCancelled() periodically from doInBackground(Object[]) to finish the task as early as possible.

Upvotes: 10

Vinnie
Vinnie

Reputation: 1730

I think calling cancel actually cancels everything from executing, including the onPostExecute. You should use your own local boolean variable and do this:

private boolean shouldContinue = true;

public void customCancel() 
{
       shouldContinue = false;
}

then in your loop do this:

if (!shouldContinue)
{
    Log.w("TAG", "task interrumped");
    return null;
}

Upvotes: 2

Guillaume
Guillaume

Reputation: 9061

Android use onCancelled() when the task is cancelled, it don't call onPostExecute!

Upvotes: 3

Related Questions