17

How can I check whether Volley gets the results of a JsonObjectRequest from the cache or from the network?

I need to show a progress dialog when it needs a network connection but not when the results are quickly received from the cache.

my request looks something like this

volleyQueue = Volley.newRequestQueue(this);
JsonObjectRequest jr = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>(){...stuff}, new Response.ErrorListener(){...errorstuff});
jr.setShouldCache(true);
volleyQueue.add(jr);
dumazy
  • 13,857
  • 12
  • 66
  • 113

5 Answers5

11

I did this by overriding Request#addMarker and checking for a "cache-hit" marker being added:

public class MyRequest<T> extends Request<T> {

    protected boolean cacheHit;

    @Override
    public void addMarker(String tag) {
        super.addMarker(tag);
        cacheHit = false;
        if (tag.equals("cache-hit")){
            cacheHit = true;
        }
    }
}
tkelly
  • 635
  • 6
  • 13
  • Wouldn't it become null again when other marker is added after cache-hit marker? There are tons of time after "Cache-hit" that Queue calls addMarker which will override cacheHit flag. – NinjaCoder Sep 24 '15 at 23:05
  • @tkelly,i have this problem:http://stackoverflow.com/questions/36678289/detect-the-number-of-new-incoming-data-in-volley-request , how can your solution?how can i use this marker? – MSepehr Apr 18 '16 at 02:29
4

Before making the Request you can get the cache from the Request Queue and check if the Entry is not null.

mRequestQueue.getCache().get("key");

The key for each request is usually the URL. I guess you should have to check if the Entry has expired too.

Emanuel Canha
  • 441
  • 5
  • 11
  • You possibly also should check that the entry is not expired, there is an `isExpired` method. I think Volley doesn't delete entries when they expire. – androidguy Feb 08 '17 at 06:07
  • Emanual, is it avoid fetching from network and fetch from cache? – Nasir Mar 06 '23 at 03:23
2

Volley has a built in way to know if image requests are immediate through the ImageContainer class, but it doesn't seem to have a similar mechanism for other requests such a JSON object request.

It seems that you have 2 main choices:

  1. You can set a timer for something like 300ms after you request the JSON (test for the best time). When the timer is done, check to see if you have the result already, otherwise show the dialog. I know this is a bit of a "hack" but it could be good enough.
  2. Edit the Volley code to add an "isImmediate" flag to every request. There are multiple ways to achieve this. I suggest starting at CacheDispatcher
Itai Hanski
  • 8,540
  • 5
  • 45
  • 65
2

Starting from Tim Kelly's answer.

by the time you check "cacheHit", it'll be reverted to false and you'll not know that it's a cache hit because many other tags are received after "cacheHit" is received and before the "onResponse" is called.

So, add

if(tag.equals("network-http-complete")){
            cacheHit = false;
        }

and remove cacheHit = false;

a fair player
  • 11,530
  • 9
  • 46
  • 48
1

adb shell setprop log.tag.Volley VERBOSE

Run this command in your terminal, you may need to set 'adb' in your path in order to use that command, it should be located in your sdk/platform-tools/ dir.

This will provide much more detailed volley logs and will show something along the lines of an execution stack for a volley request which exhibits cache hits or misses.