17

I am using Android Volley lib in my project to execute network requests, all works very well but I have some troubles with the "cancel" feature of this lib. I explain my issue..

I've an activity, where I'm executing the request at OnCreate method, the request is called, no problem. But to be sure that the cancel method works, I wanted to test and try 2 things :

  1. I fire my request and just after cancel it like this :

    MySingleton.getMyData("urltocall", getDataListener, requestTag); MySingleton.getRequestQueue().cancelAll(requestTag);

This one works! The cancel is called (I can see it too in the Request class of Volley) :

public void cancel() {
        mCanceled = true; // my breakpoint is called here
    }
  1. I fire my request and just after call finish() method of my activity and in onDestroy and/or onStop method of the activity, I'm calling the same code :

    MySingleton.getMyData("urltocall", getDataListener, requestTag); MySingleton.getRequestQueue().cancelAll(requestTag);

But this doesn't work!

The requestTag is not null and well passed to Volley, so I can't understand why the first method works but not the other one... Knowing that my purpose is to cancel request when onDestroy is called..

Thanks for your help

Yash Sampat
  • 30,051
  • 12
  • 94
  • 120
ejay
  • 1,114
  • 3
  • 14
  • 26

4 Answers4

21

My guess would be that in the first case, the request has only been added to the RequestQueue, which is why calling cancelAll() works. In the second case, there is a slight delay between starting the request and pausing/destroying the Activity: in that delay, the HTTP request has begun. You may not be aware that calling cancelAll() works only for those requests that are still in the RequestQueue. It doesn't work for an HTTP request that has already begun, there is no way to stop that.

Having said that, the documentation here implies that once a request is cancelled (i.e. by calling cancel()), it can effectively be treated as though the web service had never been called in the first place. The callbacks associated with the particular request would not be invoked (although the response received would likely be held in the local cache).

Yash Sampat
  • 30,051
  • 12
  • 94
  • 120
  • Thank you Zygoteinit ! So, it's impossible to cancel a current request, but possible to cancel future pending request right ? That's the HTTP request behavior as you said – ejay Mar 14 '15 at 17:54
  • 2
    Yes, its not possible to cancel a request that has *already begun*, for obvious reasons (a network call has to be completed once it has begun). Only those requests that are still in the `RequestQueue` can be stopped, because they have not yet begun. I hope you are able to understand this. – Yash Sampat Mar 14 '15 at 17:58
  • Yes, I understand this reason, just too bad because it can create memory leaks. Thanks for you reply ;) – ejay Mar 14 '15 at 18:13
  • @Y.S. I am in tricky situation. Lets say volley request is started and suddenly i exit my app. This is leading me to `NullPointerException` after exiting my app. I believe that fragment should exit with its activity. But even then Volley Request stays live and on reaching `ErrorLIstener` it throws nullpointer to my `Toast`. Please help. I am stuck. – Roon13 Jul 12 '15 at 06:26
  • @Roon13: apologies, [this post](http://stackoverflow.com/a/28673131/3287204) ... :) – Yash Sampat Jul 13 '15 at 18:24
  • Is there some sort of workaround for this? Please see my answer : http://stackoverflow.com/questions/34577601/how-do-you-cancel-a-volley-request-that-has-already-started – John Ernest Guadalupe Jan 03 '16 at 14:41
  • See if Volley has some built-in mechanism for dealing with this ... :) – Yash Sampat Jan 03 '16 at 16:15
  • Hi @Y.S., why do you say there is no way to cancel an already ongoing request? I couldn't find such explanation in the documentation. I'd like to see a reference about this. What is the problem to close the connection when canceling the request? – dephinera Jan 02 '18 at 15:22
  • @definera: I mean that a server request that has begun cannot be stopped, because a request that has begun can't be completely closed off from the client side. – Yash Sampat Jan 06 '18 at 15:19
8

You can cancel a Request attached to a TAG. So basically you have to add a tag with every Request.

yourRequestObject.setTag(TAG);

RequestQueue mRequestQueue;

mRequestQueue.cancelAll(TAG);

This way you can cancel all the Request with a particular TAG.

W4R10CK
  • 5,502
  • 2
  • 19
  • 30
peeyush pathak
  • 3,663
  • 3
  • 19
  • 25
7

https://developer.android.com/training/volley/simple.html#cancel

This basically says that

Once cancelled, Volley guarantees that your response handler will never be called.

So even if there is no way to undo/cancel an http request that's already begun (which makes sense), the callbacks associated with the request won't be called, which to me effectively means I can treat is a cancelled request in most scenarios even though the response thus received silently might be available in the cache.

mithril
  • 557
  • 1
  • 6
  • 10
1

I'd suggest you to cancel the added requests in onPause() method. Considering:

onPause() The system calls this method as the first indication that the user is leaving your activity (though it does not always mean the activity is being destroyed). This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back). source: Android Developers

Andy
  • 462
  • 3
  • 8
  • Hi Andy, thanks but same issue with trying in onPause(). I think ZygoteInit has right with the http request behavior, when the request has been fired, this is impossible to cancel it, but it works for other pending requests in the queue – ejay Mar 15 '15 at 01:59
  • 1
    Hi :) sure he's right, I meant you could call your function for pending requests, but on onPause instead of onStop, since I thought you would like to save some information about it :) – Andy Mar 15 '15 at 02:12
  • Yes indeed it's better to cancel in the onPause() to save some useful data too ;) – ejay Mar 15 '15 at 02:28
  • @Julien I have the onResponse() declared in the Activity class. should I check this == null in the onResponse method ? – ARK Mar 18 '16 at 18:44