Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel AsyncTask after some time

This could be a duplicate question but I did not find what I was looking for. I am calling an AsyncTask in the UI activity new LoadData().execute(); and in doInBackground I call a method which takes time. I want to interrupt this thread if the data is not return after some time. Below is the code how I tried to do this.

class LoadData extends AsyncTask<String, String, String>
{
    @Override
    protected void onPreExecute() {
    super.onPreExecute();
    startTime = System.currentTimeMillis();
    }
    protected String doInBackground(String... args)
    {

        DataCollector dc = new DataCollector();
        data = dc.collectData(query);
        //Here I check if the time is greater than 30 seconds then cancel
        if(((System.currentTimeMillis()-startTime)/1000)>30)
        {
           cancel(true);
        }
    return null;
    }
}

But this does not stop the task after 30 seconds, in fact it is taking more time. I have tried get(long timeout, TimeUnit unit); as well but that does not work either.

Can anyone show me how can I do it or how do I use isCancelled() in doInBackground.

Thanks.

like image 503
AL̲̳I Avatar asked Jun 26 '13 08:06

AL̲̳I


People also ask

How do I cancel AsyncTask?

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.

How do I stop AsyncTask when activity is destroyed?

You can either cancel the AsyncTask in the onStop method of your activity or you can let your async task finish, and not loose its progress and relink it to the next instance of your activity.

What happen if we call execute more than once in AsyncTask?

Limitation Of AsyncTask There is a limit of how many tasks can be run simultaneously. Since AsyncTask uses a thread pool executor with max number of worker threads (128) and the delayed tasks queue has fixed size 10. If you try to execute more than 138 AsyncTasks the app will crash with java. util.

What are the problems in AsyncTask?

In summary, the three most common issues with AsyncTask are: Memory leaks. Cancellation of background work. Computational cost.


Video Answer


1 Answers

You need a thread that cancels your task after a certain amount of time. That Thread could look like this:

public class TaskCanceler implements Runnable{
    private AsyncTask task;

    public TaskCanceler(AsyncTask task) {
        this.task = task;
    }

     @Override
     public void run() {
        if (task.getStatus() == AsyncTask.Status.RUNNING )
            task.cancel(true);
     }
}

And when you call your AsyncTask, you need to run the cancle task after a certain amount of time (=the timeout, in this case 20 sec)

private Handler handler = new Handler();
private TaskCanceler taskCanceler;
...
LoadData task = new LoadData();
taskCanceler = new TaskCanceler(task);
handler.postDelayed(taskCanceler, 20*1000);
task.execute(...)

It's a good idea if you clean this up on cancel or finish with

if(taskCanceler != null && handler != null) {
     handler.removeCallbacks(taskCanceler);
}

You can of course wrap this in an custom implementation of AsyncTask. I've used this pattern many times and it works like a charm. One thing to note, in rare cases the handler would not start, I suspect if you create it in the wrong context it will not survive in certain instances, so I forced the handler to be an the UI Thread with handler= new Handler(Looper.getMainLooper());

like image 56
Patrick Favre Avatar answered Sep 24 '22 02:09

Patrick Favre