0

I have an AsyncTask that calls a webservice and gets a json object from it. I want to set a timeout for this task so that if anything goes wrong(such as internet connection being disconnected or etc), the AsyncTask get cancelled. Here is my code so far:

@Override
protected void onStart() {
final GetRequestsTask requestTask = new GetRequestsTask();
requestTask.execute(createUrl());
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
      @Override
      public void run() {
          Log.d("myapp", "entered handler");
          if (requestTask.getStatus() == AsyncTask.Status.RUNNING) {
              Log.d("myapp", "entered cancelling");
              requestTask.cancel(true);
          }
      }
}, TIME_OUT);
}

The problem is that when the handler reaches "entered cancelling" point and sends the cancel signal to the AsyncTask, it won't cancel and call onCancelled() immediately (it will be called after 10 seconds or so if at all)

My GetRequestTask is linear, meaning that it does not have a loop inside it so I cannot check for isCancelled() manually inside the doInBackground() method.

What do you suggest me to do?

Cœur
  • 37,241
  • 25
  • 195
  • 267
roostaamir
  • 1,928
  • 5
  • 24
  • 51

2 Answers2

1

From this question:

If you're doing computations:

  • You have to check isCancelled() periodically.

If you're doing a HTTP request:

  • Save the instance of your HttpGet or HttpPost somewhere (eg. a public field).
  • After calling cancel, call request.abort(). This will cause IOException be thrown inside your doInBackground.

Additionally if you use some library to provide convenient requests, then I think it should have some cance() method. For example, for retrofit there is such method.

So in this case like for 'If you're doing a HTTP request' section. you need to:

  • Save the instance of your request (for retrofit it's Call)
  • After calling cancel, call 'cancel' method for saved instance of request.

And one more alternative is rxJava. With help of this library you can create Observable for your request and save reference to its subsribtion. Then you just need to call savedSubscription.unsibscribe() and that's it.

Community
  • 1
  • 1
Michael Spitsin
  • 2,539
  • 2
  • 19
  • 29
0

Yes, Asynctask takes time to call onCancelled. Basically it invokes onCancelled() when doInBackground returns. In order to resolve that, you can check isCancelled() in doInBackground frequently and as soon as it returns true, throw an exception. It will get out of doInBackground and will immediately invoke onCancelled() call back method.

Vishal
  • 1
  • 1