By default, Volley only caches data if it allows a response header. Volley caches the response based on the following response headers:
1. Cache-Control
2. Expires
3.maxAge
See below for more details.
public static Cache.Entry parseCacheHeaders(NetworkResponse response) { long now = System.currentTimeMillis(); Map<String, String> headers = response.headers; long serverDate = 0; long lastModified = 0; long serverExpires = 0; long softExpire = 0; long finalExpire = 0; long maxAge = 0; long staleWhileRevalidate = 0; boolean hasCacheControl = false; boolean mustRevalidate = false; String serverEtag = null; String headerValue; headerValue = headers.get("Date"); if (headerValue != null) { serverDate = parseDateAsEpoch(headerValue); } headerValue = headers.get("Cache-Control"); if (headerValue != null) { hasCacheControl = true; String[] tokens = headerValue.split(","); for (int i = 0; i < tokens.length; i++) { String token = tokens[i].trim(); if (token.equals("no-cache") || token.equals("no-store")) { return null; } else if (token.startsWith("max-age=")) { try { maxAge = Long.parseLong(token.substring(8)); } catch (Exception e) { } } else if (token.startsWith("stale-while-revalidate=")) { try { staleWhileRevalidate = Long.parseLong(token.substring(23)); } catch (Exception e) { } } else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) { mustRevalidate = true; } } } headerValue = headers.get("Expires"); if (headerValue != null) { serverExpires = parseDateAsEpoch(headerValue); } headerValue = headers.get("Last-Modified"); if (headerValue != null) { lastModified = parseDateAsEpoch(headerValue); } serverEtag = headers.get("ETag");
You can change the default cache policy by overriding the Request object. You can override JsonObjectRequest, for example:
public class CustomJsonObjectRequest extends JsonObjectRequest { public CustomJsonObjectRequest(int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super(method, url, jsonRequest, listener, errorListener); } public CustomJsonObjectRequest(String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super(url, jsonRequest, listener, errorListener); } @Override protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET)); return Response.success(new JSONObject(jsonString), parseIgnoreCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JSONException je) { return Response.error(new ParseError(je)); } } public static Cache.Entry parseIgnoreCacheHeaders(NetworkResponse response) { long now = System.currentTimeMillis(); Map<String, String> headers = response.headers; long serverDate = 0; String serverEtag = null; String headerValue; headerValue = headers.get("Date"); if (headerValue != null) { serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue); } serverEtag = headers.get("ETag"); final long cacheHitButRefreshed = 3 * 60 * 1000;
Update the fetchImage function as follows:
private void fetchImages() { CustomJsonObjectRequest jsObjRequest = new CustomJsonObjectRequest() (Request.Method.GET, Endpoints.product_url, (String) null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { listProduct.clear(); try { JSONArray routes = response.getJSONArray(key_product); for (int i = 0; i < routes.length(); i++) { JSONObject object = routes.getJSONObject(i); ItemCategories categories = new ItemCategories(); categories.setCategoryItem(object.getString(key_title)); categories.setUrlThumb(object.getString(key_image)); listProduct.add(categories); } adapterProductList.notifyDataSetChanged(); progressBarMain.setVisibility(View.GONE); internetError.setVisibility(View.GONE); recycleProductList.setVisibility(View.VISIBLE); } catch (JSONException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(), Toast.LENGTH_LONG).show(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { VolleyLog.d(TAG, "Error: " + error.getMessage()); } });
For reference: Android caching Volley + JSONObjectRequest