Tell Volley not to use cached data but to initiate a new request?
Asked Answered
U

2

5

I am having an issue in the app which I think it may be connected to Volley pulling data from the cache.

Namely, the app is heavily bound to the API so each change is being sent to the API and then later retrieved from the API using the Volley library. So a user will open a popup, chose some group to see its items then select some value to mark it favorite. The popup will close and the fragment will reload with new data.

When a user opens the popup again, selects the same group to load its data, the previously item will not be shown as favorite. But when a user touched the same group once more to reload its data, the item WILL BE shown as favorite.

I have debugged the code step by step and I found no error. So I concluded that Volley may be pulling data from its cache, while initiating a new API request the 2nd time I click on the group.

I would like to test if it's a cache issue or I have to debug deeper.

Is there a way to tell Volley NOT to use cached request data, but to initiate the new request to API? Something like don't use cached data, but make a new request.

NOTE: I would not like to delete the complete cache. I'd only like to tell Volley when to initiate a brand new request to the API.

Ulrikeulster answered 3/12, 2015 at 10:52 Comment(0)
B
2

IMO, if your project uses Google's volley as a module (not jar file), you can customize its classes like the following:

OPTION #1:

First file, RequestQueue.java:

add a class variable private boolean mCacheUsed = true;

and the following constructors:

    public RequestQueue(Cache cache, Network network, int threadPoolSize,
                        ResponseDelivery delivery, boolean cacheUsed) {
        mCache = cache;
        mNetwork = network;
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        mDelivery = delivery;
        mCacheUsed = cacheUsed;
    }

    public RequestQueue(Cache cache, Network network, int threadPoolSize, boolean cacheUsed) {
        this(cache, network, threadPoolSize,
                    new ExecutorDelivery(new Handler(Looper.getMainLooper())), cacheUsed);
    }

    public RequestQueue(Cache cache, Network network, boolean cacheUsed) {
        this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE, cacheUsed);
    }

then, inside public <T> Request<T> add(Request<T> request) {, you check as the following:

        // If the request is uncacheable, skip the cache queue and go straight to the network.
        if (!request.shouldCache() || !mCacheUsed) {
            mNetworkQueue.add(request);
            return request;
        }

Second file, Volley.java:

public static RequestQueue newRequestQueue(Context context, HttpStack stack, boolean cacheUsed) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network, cacheUsed);
        queue.start();

        return queue;
    }

public static RequestQueue newRequestQueue(Context context, boolean cacheUsed) {
        return newRequestQueue(context, null, cacheUsed);
    }

Finally, in MainActivity, for example:

If want to use available cache:

RequestQueue requestQueue = Volley.newRequestQueue(this, true); 

If don't want to use available cache:

RequestQueue requestQueue = Volley.newRequestQueue(this, false); 

OPTION #2:

Request.java:

Add a class variable public boolean mSkipAvailableCache = false;

RequestQueue.java:

inside public <T> Request<T> add(Request<T> request), you check as the following:

        // If the request is uncacheable, skip the cache queue and go straight to the network.
        if (!request.shouldCache() || request.mSkipAvailableCache) {
            mNetworkQueue.add(request);
            return request;
        }

MainActivity.java: You can set

jsonArrayRequest.mSkipAvailableCache = true;

available cache will not be used. Hope this helps!

Bismuth answered 4/12, 2015 at 2:30 Comment(2)
Cool! I will check this out. ThanksUlrikeulster
You made good points, but my volley is pulled from Gradle. So I am thinking to either switch to the local module or create another method for non-cached requests. This task is not in progress yet, probably the next week.Ulrikeulster
C
2

Even i had the same problem before, but you can change it using this

request.setShouldCache(false);
myQueue.add(request);
Claro answered 3/12, 2015 at 10:57 Comment(2)
So you found no other way without setShouldCache(bool)? I have a generic Volley class so all fragments use the same add request method. This way I'd have to change the logic severely (200+ locations).Ulrikeulster
ohh that's a big problem but i dont think that you can do without this because you cannot edit the volley libraries.Claro
B
2

IMO, if your project uses Google's volley as a module (not jar file), you can customize its classes like the following:

OPTION #1:

First file, RequestQueue.java:

add a class variable private boolean mCacheUsed = true;

and the following constructors:

    public RequestQueue(Cache cache, Network network, int threadPoolSize,
                        ResponseDelivery delivery, boolean cacheUsed) {
        mCache = cache;
        mNetwork = network;
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        mDelivery = delivery;
        mCacheUsed = cacheUsed;
    }

    public RequestQueue(Cache cache, Network network, int threadPoolSize, boolean cacheUsed) {
        this(cache, network, threadPoolSize,
                    new ExecutorDelivery(new Handler(Looper.getMainLooper())), cacheUsed);
    }

    public RequestQueue(Cache cache, Network network, boolean cacheUsed) {
        this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE, cacheUsed);
    }

then, inside public <T> Request<T> add(Request<T> request) {, you check as the following:

        // If the request is uncacheable, skip the cache queue and go straight to the network.
        if (!request.shouldCache() || !mCacheUsed) {
            mNetworkQueue.add(request);
            return request;
        }

Second file, Volley.java:

public static RequestQueue newRequestQueue(Context context, HttpStack stack, boolean cacheUsed) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network, cacheUsed);
        queue.start();

        return queue;
    }

public static RequestQueue newRequestQueue(Context context, boolean cacheUsed) {
        return newRequestQueue(context, null, cacheUsed);
    }

Finally, in MainActivity, for example:

If want to use available cache:

RequestQueue requestQueue = Volley.newRequestQueue(this, true); 

If don't want to use available cache:

RequestQueue requestQueue = Volley.newRequestQueue(this, false); 

OPTION #2:

Request.java:

Add a class variable public boolean mSkipAvailableCache = false;

RequestQueue.java:

inside public <T> Request<T> add(Request<T> request), you check as the following:

        // If the request is uncacheable, skip the cache queue and go straight to the network.
        if (!request.shouldCache() || request.mSkipAvailableCache) {
            mNetworkQueue.add(request);
            return request;
        }

MainActivity.java: You can set

jsonArrayRequest.mSkipAvailableCache = true;

available cache will not be used. Hope this helps!

Bismuth answered 4/12, 2015 at 2:30 Comment(2)
Cool! I will check this out. ThanksUlrikeulster
You made good points, but my volley is pulled from Gradle. So I am thinking to either switch to the local module or create another method for non-cached requests. This task is not in progress yet, probably the next week.Ulrikeulster

© 2022 - 2024 — McMap. All rights reserved.