geekkoz
geekkoz

Reputation: 3674

Cancel All Volley Requests Android

At the moment i´m using mRequestQueue.cancelAll(getActivity()) at on stop method in a fragment but apparently when i move the phone from landscape to portrait it is still returning the data made in the request but causing crash because the holders for the data dosent exist anymore. any sample code of how to do it properly?

Upvotes: 23

Views: 32799

Answers (9)

Osama Remlawi
Osama Remlawi

Reputation: 2990

In Kotlin

  requestQueue?.cancelAll { true }

Upvotes: 1

Ravneet Singh
Ravneet Singh

Reputation: 1

I've struggled with the memory leak for the longest time until I found I called stop() from the class 'RequestQueue'.

//Initialize the object
RequestQueue requestQueue = 
        Volley.newRequestQueue(getActivity().getApplicationContext());

//Release the object
requestQueue.stop();
requestQueue = null;

The class says it "Stops the cache and network dispatchers." Whatever that means...

Upvotes: -1

Samira
Samira

Reputation: 81

In Case Of Fragment; Use only One RequestQueue rQueue; Initialize it in OnCreate method; And use it for all volley request; and at the end

@Override

public void onStop () {

    super.onStop();
    if (rQueue != null) {
        rQueue.cancelAll(this);
    }
}

Upvotes: 0

pjco
pjco

Reputation: 3836

You should set the tag to an object, not a method.

By setting the tag to getActivity(), you are asking Volley to use a dynamic method call on the main thread as a reference to the request which is happening on a background thread.

So when the background thread is trying to cancel the requests, the activity could already be dead.


Rather than using getActivity(), use this or some other object or string.

This is good practice for any Tag, and you should also beware of leaking your activity.

Solutions:


You could use the current object:

request.setTag(this);

or, the static class object

request.setTag(MyFragment.class);

or, as a constant in a separate class:

request.setTag(CustomTags.LIST_REQUESTS);

CustomTags.LIST_REQUESTS being the best in my opinion (less chance of leaking activity)

Something like this:

public class CustomTags
{
    public static final String LIST_REQUESTS="CustomTags:LIST_REQUESTS";
}

Update

I just noticed I was making a mistake in tagging my requests in Volley (though the solutions I posted above are fine).

I still thought I would update here an important thing to keep in mind. Volley tags by identity not value.

Thus, it is important to keep in mind that a tag that is merely the same string value, and not the same object itself, will not be recognized as the same tag.

It's similar to the difference between

String a1 = "A";
String a2 = "A";
a1 == a2;  //evaluates to false

String a1 = "A";
String a2 = "A";
a1.equals(a2); // evaluates to true

Upvotes: 19

Lefteris
Lefteris

Reputation: 14677

I know this answer comes in late, but in case anyone else is having this problem:

In my implementation the Tag was being set (and overwritten) at the point where the request was added to the queue.

So despite that I was cancelling the request with my Tag, the tag on the request queue was not the same (as it was previously overwritten) and it was not cancelled.

Logging the requests running and printing out the tags, led me to the solution:

mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
    @Override
        public boolean apply(Request<?> request) {
        Log.d("DEBUG","request running: "+request.getTag().toString());
            return true;
        }
});

Upvotes: 4

gorjan5sk
gorjan5sk

Reputation: 691

Instead of using a tag for cancelAll, make an all-pass RequestFilter.

mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
    @Override
        public boolean apply(Request<?> request) {
            return true;
        }
    });

EDIT: This cancels all Requests from all activities/fragments, and doesn't work favorably with the Activity Lifecycle. The best way to manage this is to add a String tag unique to your fragment.

Upvotes: 59

Pieces
Pieces

Reputation: 2295

Are you setting the tag of the requests to the activity? That's the only way the code you are providing will work. The cancelAll method searches all of the requests with the tag of whatever tag you provided and cancels them.

Upvotes: 0

Zheko
Zheko

Reputation: 703

Which tag did you use when making the requests? If you didn't set a tag on each of your requests it may never work. As far as I see, Volley does NOT automatically set a tag for your requests

Upvotes: 3

senneco
senneco

Reputation: 1871

If you add request to queue from framgment, you should cancel like this: mRequestQueue.cancelAll(this) . And sorry if it didn't work - i didn't test this solution. But i hope this help to you.

Upvotes: 1

Related Questions