Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 258
sandalone Avatar asked Sep 26 '22 01:09

sandalone


2 Answers

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!

like image 147
BNK Avatar answered Oct 13 '22 09:10

BNK


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

request.setShouldCache(false);
myQueue.add(request);
like image 2
Rahul Avatar answered Oct 13 '22 10:10

Rahul